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 asresult.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:
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.