Skip to main content

PandaProbe Harness

PandaProbe Harness evaluates any developer-owned, PandaProbe-instrumented task agent and maintains a shared learned-rules workspace with a separate, package-owned repair agent.

PyPI CI Python License

Ownership model

The developer owns the task agent, model, framework, prompts, domain tools, execution loop, and environment. PandaProbe owns task instrumentation and evaluation, trajectory detection, diagnostic notices, the managed repair-agent loop, workspace administration, validation, and read-only rule delivery.

Task and repair activity are isolated:

developer task agent → task trace → evaluation/gate → notice
                                                ↓
                                  PandaProbe managed repair
                                                ↓
                                     candidate rule
                                                ↓
developer task agent ── read-only tools ──→ shared workspace

The task agent never reads notices, inspects diagnostic traces, acknowledges notices, writes or retires rules, or controls validation. Its harness tools are exactly harness_rules_read, harness_rules_search, harness_rules_list, and harness_rule_status, all read-only.

Learned rules are read on demand, never injected

system_context() never includes rule bodies or an expanded rule-file index and performs no implicit rule read or search. It contains only a stable note that learned rules are available through those four tools. The task agent decides whether and when to list scopes, search, or read one. Workspace rules.md holds SKILL-style task-facing instructions and the compact generated scope index; each entry carries a bounded description and active/provisional counts, never rule text.

Scope: where a rule is filed

Managed repair decides, from the failure evidence it already has, whether a rule is broadly applicable or belongs to a specific context. That decision is part of the existing repair call — no extra model round.

  • global is the default: broadly reusable rules, not tied to one task, workflow, application, tool, or domain.
  • A concise contextual name — an application, workflow, or domain drawn from the evidence — is preferred whenever the rule really belongs to that context. The catalog is open, and a new name simply creates its rules/<scope>.md.
  • scoped is the fallback: the rule is specific, but no meaningful stable name could be determined.

Scope naming is generic and not tied to any benchmark or integration; a host's own label for itself is rejected as a scope. Hosts may pass bounded RuleScopeHint metadata and a short task_summary to inform the decision, but neither dictates it. PandaProbe normalizes names only for filename safety, owns the resulting path, and imposes no prefix convention.

Validation decides promotion and retirement

A new rule enters as a provisional candidate and only validation promotes or retires it — never the repair agent. Replay is the strong path; a cheap forward trial over live sessions decides candidates replay cannot reach, so every candidate reaches a verdict. Call settle_validation() at a phase boundary before snapshotting or reporting a ruleset.

Installation

pip install pandaprobe-harness

Managed repair uses PandaProbe's official LiteLLM wrapper. The same normalized path accepts LiteLLM identifiers for OpenAI, Anthropic API, Anthropic on Bedrock, and Gemini on Vertex AI:

openai/...
anthropic/...
bedrock/anthropic....
vertex_ai/...

No potentially billable model is selected by default. Configure one explicitly with repair_model= or HARNESS_REPAIR_MODEL. Provider credentials and cloud settings follow LiteLLM conventions.

Generic task-loop integration

from pandaprobe_harness import Harness, HarnessConfig, RuleScopeHint
from pandaprobe_harness.agent_tools.native import as_anthropic_tools

harness = Harness.create(
    HarnessConfig(
        repair_model="openai/gpt-...",
        repair_timeout_s=60,
        repair_max_turns=6,
        repair_max_tokens=4096,
        repair_temperature=None,
        repair_reasoning_effort="none",  # current OpenAI reasoning models + tools
        trace_repair_agent=False,
        domain_policy="Describe authorized domain behavior here.",
    )
)

async def one_turn(session_id: str, user_input: str) -> str:
    context = harness.system_context(session_id, task_hint=user_input)
    rule_specs, rule_dispatch = as_anthropic_tools(harness.task_tools)

    # You still construct and run your own agent with your own domain tools.
    answer = await my_agent_step(
        system_prompt=context + MY_PROMPT,
        tools=[*my_domain_tools, *rule_specs],
        tool_dispatch=rule_dispatch,
        user_input=user_input,
    )

    # Flush/export task tracing first, then register the completed task turn.
    harness.on_turn_end({
        "session_id": session_id,
        "turn_index": next_index(),
        "end_state": end_state(),
        "rule_scope_hints": [
            RuleScopeHint(
                key="payments",
                description="Payment authorization and transaction workflows.",
            ).to_json()
        ],
    })
    settlement = await harness.settle(session_id)
    return answer

The host must settle before starting the next task turn when same-session repair is desired. Settlement waits for task evaluation, notice persistence, and one bounded managed repair attempt. It does not synchronously wait for domain replay validation. A candidate is immediately discoverable through list/read after settlement, but is never inserted into the next prompt; validation may promote or retire it later.

Before a task turn, the host may attach the stable capability preamble and four read-only tools. The harness injects no learned content and makes no automatic rule-tool call. After the turn, tracing is flushed, evaluation/gating run, related notices are grouped into one bounded repair episode, and managed repair may add at most one provisional candidate or resolve without one. Successful settlement atomically refreshes the index/scope artifacts before the next task turn can query them; timeout or failure leaves every notice recoverable.

settlement.repair exposes status, repair/task session IDs, repair episode and notice IDs, recommended/selected scope, considered/existing/candidate rule IDs, suppression reason, model turns/tool calls, normalized usage when available, and error category. Repair failure or timeout never fails the developer task.

Framework turn detectors remain available through Harness.for_langgraph(), for_langchain(), for_deepagents(), for_crewai(), for_claude_agent_sdk(), and for_openai_agents().

Configuration

Managed repair fields and environment equivalents are:

Field Environment
repair_model HARNESS_REPAIR_MODEL
repair_timeout_s HARNESS_REPAIR_TIMEOUT_S
repair_max_turns HARNESS_REPAIR_MAX_TURNS
repair_max_tokens HARNESS_REPAIR_MAX_TOKENS
repair_temperature HARNESS_REPAIR_TEMPERATURE
repair_reasoning_effort HARNESS_REPAIR_REASONING_EFFORT
trace_repair_agent HARNESS_TRACE_REPAIR_AGENT
domain_policy HARNESS_DOMAIN_POLICY

observe_only=True remains non-mutating and does not require a repair model. Managed repair requires rule_validation=True, so a repair-authored rule can never skip the candidate lifecycle. Task tracing is unchanged when repair tracing is disabled. When enabled, the PandaProbe SDK records repair completions under repair-<task-session>-<episode-id> with repair-role metadata; exact-session task trace discovery excludes them.

Each enabled repair run exports one trace named pandaprobe. Its harness CHAIN span contains repeated repair-agent and tools AGENT spans; each repair-agent contains the official wrapper's litellm-chat LLM span, and each tools span contains one TOOL child per restricted workspace operation. No second tool-only trace is created.

Offline examples and operator tools

uv run python examples/misc/offline_self_heal.py
uv run python examples/misc/closed_loop_self_heal.py
uv run python examples/misc/calibration_demo.py

The examples use deterministic completion fakes and require no credentials. Operator-only CLIs remain pandaprobe-harness-eval for regression replay and pandaprobe-harness-calibrate for threshold calibration. The former task-administration companion CLI has been removed.

Development

uv run pytest -q
uv run ruff check .
uv run mypy

See CHANGELOG.md for migration notes and CONTRIBUTING.md for project invariants.

License

MIT © Chirpz AI

Metadata

Release files for pandaprobe-harness 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pandaprobe-harness 0.9.0
File Size Uploaded Provenance Actions
pandaprobe_harness-0.9.0.tar.gz 1.0 MB With provenance Details for pandaprobe_harness-0.9.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pandaprobe-harness 0.9.0
File Interpreter ABI Platform Actions
pandaprobe_harness-0.9.0-py3-none-any.whl Python 3 none any Details for pandaprobe_harness-0.9.0-py3-none-any.whl

Total release size: 1.2 MB

Release files / pandaprobe_harness-0.9.0.tar.gz

Download URL pandaprobe_harness-0.9.0.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
67ddd684fe357d94bf147134e5870b0d40b6039177e74d5666538cdc51ae5977
BLAKE2b-256 checksum
How to use checksums
c4c224ecae7acaaefbddb86ef4fc41611acb028b8a2c5f25aac257c57905cc03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / pandaprobe_harness-0.9.0-py3-none-any.whl

Download URL pandaprobe_harness-0.9.0-py3-none-any.whl
Size 157.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6b43d1d7ccef88e5af8af607d843e3f68ac2b37f6cde4de5bae5eae1f4644c86
BLAKE2b-256 checksum
How to use checksums
ce6d429a3eb4973f94ba1af88ff135e778daae75004297bbb2d31b4512eb726f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Security for pandaprobe-harness 0.9.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pandaprobe_harness-0.9.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page