Skip to main content
Assertions are ordinary pytest assert statements. Deterministic ones are free and fast, so put them before any judge(...) call - pytest stops at the first failure, and a failed assertion never spends judge tokens. case.run(...) returns a compact CaseResult: check visible dialogue in .messages, evaluated data in .output, the stop condition in .termination, and what the agent did in .trace. Pass trace=result.trace to judge(...) only when the criterion needs trajectory evidence.

Trace assertions

Successful runs expose the collected trace as result.trace.

Tool calls

result.trace.tools answers questions about which tools were invoked and what JSON evidence each call recorded:
Argument and result filters are recursive JSON object subsets. Every expected key must exist. Nested objects use the same subset rule. Arrays and scalar values require exact JSON type and value equality, so true does not match 1, and array order and length matter. Observed objects may have extra keys. Omit arguments, result, or status to leave that field unfiltered. Supplying an empty object matches a recorded object, but never a missing payload or a recorded scalar or array. Filters must be mappings; inspect tools.calls directly for exact scalar or array assertions. Missing and explicit JSON null are separate facts:
Repeated names produce separate calls with separate zero-based sequence values. matching(...) returns all matching calls. Independent assertions do not reserve or assign a call, so the same observed call can satisfy more than one assertion. Kensa reports captured facts only. A successful tool span can return any application payload, including a field named status; Kensa does not infer whether that payload means the business operation succeeded.

Resource bounds

result.trace also reports cost, turns, and latency for budget assertions:
result.trace.incomplete is True when the trace could not be fully collected. Guard budget assertions on it if your harness can return early.

Output assertions

case.run(kensa_run) always returns CaseResult. Assert on its typed fields with plain Python.

Assertions gate the judge

Order matters. Deterministic assertions first, semantic judge last:
If a tool assertion fails, the test fails immediately and the LLM judge never runs. See Judge for the semantic half.
Last modified on July 30, 2026