Harness.for_<framework>() factory wires the framework’s natural turn boundary to on_turn_end and preserves its session resolution (session identity comes from the PandaProbe SDK’s session context, so harness evaluations and SDK traces line up automatically).
Adapters are optional, import-guarded extras:
- pip
- uv
session_id= (a fixed session for single-conversation processes), config=, cli=, and replay= for closed-loop validation. To wire a ground-truth outcome oracle, use Harness.create(verifier=...) — the for_* factories do not take verifier=.
Turn granularity matters
The barrier with an adapter
Adapters callon_turn_end for you, which is fire-and-forget. To get in-session healing, await the barrier after the framework’s turn returns:
harness.turn(session_id, settle=True) is the equivalent when you own the boundary; with an adapter, the explicit settle() after the framework call is the same thing. See the barrier.
LangGraph (LangChain & DeepAgents work the same way)
CrewAI
Claude Agent SDK
OpenAI Agents SDK
Rebuilding the preamble per turn
You no longer need to. The task preamble is a constant — one sentence naming four read-only tools — so a prompt fixed at construction time is identical to one rebuilt every turn. Frameworks that pin the system prompt lose nothing. What the agent reads is always current regardless, becauseharness_rules_read and harness_rules_list render from the live store at call time.
Runnable end-to-end sketches for every framework live in the repository’s examples/misc/ directory.
