Metadata-Version: 2.4
Name: warrantd
Version: 0.1.0
Summary: A warrant daemon for agent actions — earned autonomy with an audit trail.
Project-URL: Homepage, https://github.com/moritzkazooba-wq/warrantd
Project-URL: Repository, https://github.com/moritzkazooba-wq/warrantd
Author: Moritz
License: MIT
License-File: LICENSE
Keywords: agents,approval,audit,autonomy,guardrails,trust
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# warrantd

[![PyPI version](https://img.shields.io/pypi/v/warrantd.svg)](https://pypi.org/project/warrantd/)
[![Python versions](https://img.shields.io/pypi/pyversions/warrantd.svg)](https://pypi.org/project/warrantd/)
[![CI](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml/badge.svg)](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)

> A warrant daemon for agent actions — earned autonomy with an audit trail.

`warrantd` answers one question for an agent that wants to take an action:
**ALLOW, REQUIRE_APPROVAL, or BLOCK?** — and governs how an action class *earns*
more autonomy over time. It is a standalone, framework-agnostic trust primitive:
it knows nothing about Slack, Stripe, OpenAI, Anthropic, FastAPI, or any
transport/provider/store. Your app supplies those by implementing three small
protocols.

See [`warrantd-spec.md`](./warrantd-spec.md) for the authoritative design.

## Install

```bash
uv add warrantd        # or: pip install warrantd
```

## Define a policy

```python
from decimal import Decimal
from warrantd import (
    ActionClass, AutonomyState, GraduationThresholds, RiskTier, TrustPolicy,
)

policy = TrustPolicy(
    actions={
        "read_ledger": ActionClass(name="read_ledger", risk=RiskTier.READ),
        "issue_refund": ActionClass(
            name="issue_refund",
            risk=RiskTier.REVERSIBLE_WRITE,
            auto_cap=Decimal("100"),    # auto-approve at/below this
            hard_cap=Decimal("1000"),   # never auto-approve above this
        ),
    },
    thresholds=GraduationThresholds(
        pass_rate={AutonomyState.SUPERVISED: 0.80, AutonomyState.AUTONOMOUS: 0.95},
        adversarial_pass_rate={AutonomyState.SUPERVISED: 0.70, AutonomyState.AUTONOMOUS: 0.90},
        min_samples={AutonomyState.SUPERVISED: 50, AutonomyState.AUTONOMOUS: 200},
    ),
)
```

## Gate an action

Implement `MetricsProvider` and `AuditSink` (and optionally `ApprovalGate`),
then call `evaluate()` before every tool execution and `record()` after:

```python
from warrantd import ActionRequest, TrustLayer, Verdict

trust = TrustLayer(policy=policy, metrics=my_metrics, audit=my_audit)

decision = trust.evaluate(ActionRequest("issue_refund", tenant_id="acme", value=Decimal("250")))
if decision.verdict is Verdict.ALLOW:
    ...  # execute
elif decision.verdict is Verdict.REQUIRE_APPROVAL:
    ...  # route to your ApprovalGate
else:
    ...  # BLOCK
```

A runnable end-to-end example with in-memory stubs lives in
[`examples/quickstart.py`](./examples/quickstart.py).

## How autonomy is earned

Each action class advances `MANUAL → SUPERVISED → AUTONOMOUS` only when its eval
metrics clear the thresholds for the target state, subject to a per-class policy
ceiling (`max_state`) and a risk ceiling for `CONSEQUENTIAL` actions. The
graduation function is pure and deterministic — no LLM, no randomness — so the
same metrics always yield the same allowed state.

## Documentation

A comprehensive, self-contained reference lives at
[`docs/warrantd-notebooklm.md`](./docs/warrantd-notebooklm.md). It explains the
concepts, the graduation model, the decision flow, the full API, worked
examples, a glossary, and an FAQ in prose form — written to be dropped into
NotebookLM (or any RAG system) as a single knowledge source.

## Development

```bash
uv sync --all-extras --dev
uv run ruff check .
uv run mypy --strict warrantd
uv run pytest --cov=warrantd
```

## Releasing

Releases publish to PyPI via [OIDC trusted publishing][tp] — no API tokens are
stored. One-time setup: register the `warrantd` trusted publisher on PyPI
(repo `moritzkazooba-wq/warrantd`, workflow `release.yml`, environment `pypi`).
Then:

1. Bump the version in `pyproject.toml` and `warrantd/__init__.py`, update
   `CHANGELOG.md`, and tag (`vX.Y.Z`).
2. (Optional) Run the **release** workflow manually with target `testpypi` to
   rehearse the upload.
3. Cut a GitHub Release — the workflow builds, runs `twine check`, and publishes
   to PyPI.

[tp]: https://docs.pypi.org/trusted-publishers/

## License

MIT — see [LICENSE](./LICENSE).
