Skip to main content

Governed execution trees for AI agents: budget it, gate it, replay it.

Project description

pollard

Governed execution trees for AI agents: budget it, gate it, replay it.

pip install pollard
from pollard import Budget, Runtime
from examples.mock_model import call_model

rt = Runtime("runs.db")
with rt.run("triage", budget=Budget(tokens=120_000, depth=8)) as run:
    node = run.model_call(
        {"model": "mock-1", "messages": [{"role": "user", "content": "Summarize: ..."}]},
        fn=call_model,
    )
    print(node.result["text"])
    print(run.report())

pollard is a runtime primitive, not an agent framework. It records each step as a node in a content-addressed tree. Node identity is a hash of the step inputs, parent identity, kind, and attempt number, so the tree gives you a control-flow ledger without owning your model client, tools, prompts, or loop.

What you get:

  • Budget: refuse a step before it runs when a known budget would be exceeded.
  • Branch and rollback: make alternate children, move the cursor back, and keep shared history.
  • Audit: each node id commits to its ancestry and identity payload.
  • Registry firewall: registered tool calls resolve against a versioned action set or fail closed.
  • Replay: record semantic steps once, then serve stored results in tests and CI.

Budget semantics are honest about what can be controlled. If a precheck estimate proves a step would exceed budget, pollard records a refusal node and does not call your function. If the actual result charge exceeds budget after the function returns, that node still stands because the spend already happened; later steps are refused.

Limits in v0.3:

  • Replay of sampled model calls serves the recorded output. It does not re-check that a provider would return that output again.
  • Hosted API energy use is not measured. The NVML energy meter is for local GPU inference only.
  • A SQLite store assumes one writer process.
  • The audit tree is tamper-evident, not tamper-proof. Verification detects changed history, but it cannot stop deletion of the whole store file.

Registry Firewall

With a registry installed, tool_call cannot execute an arbitrary caller-supplied function. The runtime resolves the tool name and version against ActionSpec, validates arguments against the supported schema subset, records the spec_digest and registry_digest, then runs the registered handler. Unknown tools, version mismatch, invalid args, policy denial, and missing confirmation all produce refusal nodes.

This is structural gating, not content judgment. A content firewall tries to decide whether a requested action is safe. pollard answers a narrower audit question: was this action in the declared, versioned set, with arguments that match its schema, under the recorded policy state?

Dry-run mode records side-effectful registered actions without executing their handlers. This is useful for reviewing an intended action transcript before allowing writes.

How it compares:

  • LangGraph and related graph runtimes execute a graph you author ahead of time. pollard ledgers the control flow your code performs and can wrap calls inside a graph node.
  • pydantic-ai, smolagents, and the OpenAI Agents SDK own more of the agent loop. pollard is bring-your-own-client and has zero core runtime dependencies.
  • Action firewall products judge tool calls by content policy. pollard uses structural registry gating: an action resolves against a versioned registry or it does not execute.
  • HTTP recorders pin transport bytes. pollard pins semantic steps, so recordings can outlive SDK or provider changes.

Record And Replay

Runtime(mode=...) accepts three modes:

  • record: execute the function and store the result.
  • hybrid: serve a stored result when the computed node id already exists, otherwise execute and store.
  • replay: never call the function. A missing result raises MissingRecording.

Replay mode verifies the stored node ancestry before serving a result. When hybrid or replay serves a stored result, run.report()["avoided"] records the charges that were skipped for that run.

For pytest, install pollard with the dev extra or with pytest available, then use the fixture:

def test_agent(pollard_run):
    node = pollard_run.model_call(payload, fn=real_client)
    assert "invoice" in node.result["text"].lower()

Run with --pollard-mode=record, --pollard-mode=hybrid, or --pollard-mode=replay. The fixture stores small SQLite recordings under tests/pollard_recordings/ by default.

See examples/ for offline scripts that run without network access.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pollard-0.3.0.tar.gz (37.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pollard-0.3.0-py3-none-any.whl (30.7 kB view details)

Uploaded Python 3

File details

Details for the file pollard-0.3.0.tar.gz.

File metadata

  • Download URL: pollard-0.3.0.tar.gz
  • Upload date:
  • Size: 37.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for pollard-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e864ca97da22aba6e6f05d1b20b646c11b5e20ae2b409769c00c1da089b06f2d
MD5 b5efbbbb8a45cb140c0dcf5c468569ec
BLAKE2b-256 cae538e3f7713c571b899acdf3c7a04f05787bad510ade6338e62cc941df4873

See more details on using hashes here.

File details

Details for the file pollard-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: pollard-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 30.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for pollard-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fd4922b049b5407f36dce22c07ee269c152441217287bbdd0fc13168393702cd
MD5 9a01dd5b5d32e5c7bbe933a74806c5fe
BLAKE2b-256 e6992098b4120367882d3e5871bd6db28295549668eab8dcd634a49fb2005a19

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page