Harness.create() provisions the workspace, wires every component (hook, mailbox, journal, rules, eval set, toolset, restricted shell), and schedules the startup health check. It accepts an explicit HarnessConfig and, for the closed loop, your replay function:
1. The system context
2. The tools
as_langchain_tools and as_openai_function_tools cover the other native formats, and the pandaprobe-harness-agent companion CLI covers sandboxed shells — see the toolset.
3. The turn boundary
Three equivalent styles — pick whichever fits your loop:end_state you pass is what a captured eval case will carry as its replay input:
Use the same session id for the harness turn and the SDK trace context (
pandaprobe.session(session_id)) — the evaluation scores whatever traces landed under that session.Determinism helpers
Everything afteron_turn_end is detached and non-blocking. When a test or script needs to observe results deterministically:
drain_timeout_s) for callers’ convenience — correctness never depends on them; each background task handles its own result.
Everything on the facade
| Surface | Purpose |
|---|---|
harness.system_context(task_hint=None) | The prompt preamble: rules + protocol + banner. |
harness.toolset / harness.shell | The 14 operations; the restricted shell for sandboxed delivery. |
harness.turn() / run_turn() / on_turn_end() | Turn boundaries. |
harness.refresh() / refresh_all() / drain_validation() | Bounded joins. |
harness.run_regression(sample=None) | Replay the eval set against the current rules. |
harness.validate_candidates() | Run one candidate-validation round now. |
harness.mailbox / journal / rules / evalset / config | Direct store access for inspection and scripting. |
harness.check_health() | The memoized CLI/auth probe. |

