warrantd 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- warrantd-0.1.0/.github/workflows/ci.yml +38 -0
- warrantd-0.1.0/.github/workflows/release.yml +71 -0
- warrantd-0.1.0/.gitignore +20 -0
- warrantd-0.1.0/CHANGELOG.md +30 -0
- warrantd-0.1.0/CLAUDE.md +33 -0
- warrantd-0.1.0/LICENSE +21 -0
- warrantd-0.1.0/PKG-INFO +137 -0
- warrantd-0.1.0/README.md +116 -0
- warrantd-0.1.0/docs/warrantd-notebooklm.md +1013 -0
- warrantd-0.1.0/examples/quickstart.py +115 -0
- warrantd-0.1.0/pyproject.toml +63 -0
- warrantd-0.1.0/tests/conftest.py +69 -0
- warrantd-0.1.0/tests/test_decision.py +177 -0
- warrantd-0.1.0/tests/test_graduation.py +145 -0
- warrantd-0.1.0/tests/test_idempotency.py +65 -0
- warrantd-0.1.0/tests/test_killswitch.py +89 -0
- warrantd-0.1.0/uv.lock +552 -0
- warrantd-0.1.0/warrantd/__init__.py +46 -0
- warrantd-0.1.0/warrantd/audit.py +25 -0
- warrantd-0.1.0/warrantd/autonomy.py +23 -0
- warrantd-0.1.0/warrantd/core.py +150 -0
- warrantd-0.1.0/warrantd/decision.py +70 -0
- warrantd-0.1.0/warrantd/graduation.py +58 -0
- warrantd-0.1.0/warrantd/killswitch.py +42 -0
- warrantd-0.1.0/warrantd/policy.py +27 -0
- warrantd-0.1.0/warrantd/protocols.py +36 -0
- warrantd-0.1.0/warrantd/py.typed +0 -0
- warrantd-0.1.0/warrantd/risk.py +24 -0
- warrantd-0.1.0/warrantd-spec.md +187 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
check:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v5
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
run: uv python install ${{ matrix.python-version }}
|
|
21
|
+
|
|
22
|
+
- name: Sync dependencies
|
|
23
|
+
run: uv sync --all-extras --dev
|
|
24
|
+
|
|
25
|
+
- name: Lint
|
|
26
|
+
run: uv run ruff check .
|
|
27
|
+
|
|
28
|
+
- name: Type-check
|
|
29
|
+
run: uv run mypy --strict warrantd
|
|
30
|
+
|
|
31
|
+
- name: Test (with coverage gate on graduation.py and decision.py)
|
|
32
|
+
run: >
|
|
33
|
+
uv run pytest
|
|
34
|
+
--cov=warrantd
|
|
35
|
+
--cov-report=term-missing
|
|
36
|
+
--cov-fail-under=90
|
|
37
|
+
--cov=warrantd/graduation.py
|
|
38
|
+
--cov=warrantd/decision.py
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Publishes warrantd to PyPI via OIDC trusted publishing — no API tokens.
|
|
4
|
+
#
|
|
5
|
+
# Setup (one-time, on PyPI):
|
|
6
|
+
# 1. Create the `warrantd` project's trusted publisher pointing at this repo,
|
|
7
|
+
# workflow `release.yml`, and environment `pypi`.
|
|
8
|
+
# 2. (Optional) Do the same on TestPyPI with environment `testpypi`.
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# - Cut a GitHub Release -> builds and publishes to PyPI.
|
|
12
|
+
# - Run manually (workflow_dispatch) and pick `testpypi` to rehearse first.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
release:
|
|
16
|
+
types: [published]
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
inputs:
|
|
19
|
+
target:
|
|
20
|
+
description: "Package index to publish to"
|
|
21
|
+
type: choice
|
|
22
|
+
options: [testpypi, pypi]
|
|
23
|
+
default: testpypi
|
|
24
|
+
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
build:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Install uv
|
|
35
|
+
uses: astral-sh/setup-uv@v5
|
|
36
|
+
|
|
37
|
+
- name: Build sdist and wheel
|
|
38
|
+
run: uv build
|
|
39
|
+
|
|
40
|
+
- name: Check distribution metadata
|
|
41
|
+
run: uvx twine check dist/*
|
|
42
|
+
|
|
43
|
+
- name: Upload build artifacts
|
|
44
|
+
uses: actions/upload-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/
|
|
48
|
+
|
|
49
|
+
publish:
|
|
50
|
+
needs: build
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
# A GitHub Release always targets PyPI; a manual run uses the chosen index.
|
|
53
|
+
environment: ${{ github.event_name == 'release' && 'pypi' || inputs.target }}
|
|
54
|
+
permissions:
|
|
55
|
+
id-token: write # required for OIDC trusted publishing
|
|
56
|
+
steps:
|
|
57
|
+
- name: Download build artifacts
|
|
58
|
+
uses: actions/download-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: dist
|
|
61
|
+
path: dist/
|
|
62
|
+
|
|
63
|
+
- name: Publish to PyPI
|
|
64
|
+
if: ${{ github.event_name == 'release' || inputs.target == 'pypi' }}
|
|
65
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
66
|
+
|
|
67
|
+
- name: Publish to TestPyPI
|
|
68
|
+
if: ${{ github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi' }}
|
|
69
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
70
|
+
with:
|
|
71
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
|
|
9
|
+
# Tooling caches
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.coverage
|
|
14
|
+
.coverage.*
|
|
15
|
+
htmlcov/
|
|
16
|
+
coverage.xml
|
|
17
|
+
|
|
18
|
+
# Virtual envs
|
|
19
|
+
.venv/
|
|
20
|
+
venv/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-06-09
|
|
10
|
+
|
|
11
|
+
Initial public release.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- `TrustLayer` facade with a pure `evaluate()` decision flow
|
|
15
|
+
(kill switch → earned autonomy state → caps/value → verdict) and a
|
|
16
|
+
deterministic `idempotency_key`.
|
|
17
|
+
- Pure, deterministic `GraduationEngine` computing the highest earned
|
|
18
|
+
`AutonomyState` from eval metrics, clamped by a per-class policy ceiling.
|
|
19
|
+
- Core value types: `RiskTier`, `AutonomyState`, `Verdict`, `ActionClass`,
|
|
20
|
+
`ActionRequest`, `EvalMetrics`, `Decision`, `TrustPolicy`,
|
|
21
|
+
`GraduationThresholds`, `AuditEntry`.
|
|
22
|
+
- Boundary protocols implemented by the consuming app: `MetricsProvider`,
|
|
23
|
+
`ApprovalGate`, `AuditSink`.
|
|
24
|
+
- `KillSwitch` with global and per-action trips; configurable tripped verdict
|
|
25
|
+
(`BLOCK` or `REQUIRE_APPROVAL`).
|
|
26
|
+
- `py.typed` marker; ships fully typed and `mypy --strict` clean.
|
|
27
|
+
- Runnable `examples/quickstart.py` with in-memory stubs.
|
|
28
|
+
|
|
29
|
+
[Unreleased]: https://github.com/moritzkazooba-wq/warrantd/compare/v0.1.0...HEAD
|
|
30
|
+
[0.1.0]: https://github.com/moritzkazooba-wq/warrantd/releases/tag/v0.1.0
|
warrantd-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code when working in this repository.
|
|
4
|
+
|
|
5
|
+
## Source of truth
|
|
6
|
+
|
|
7
|
+
[`warrantd-spec.md`](./warrantd-spec.md) is the authoritative build spec for this
|
|
8
|
+
project — architecture, the core decision model, and the public API. **Read it
|
|
9
|
+
before making changes** and implement to the interfaces it defines. Do not
|
|
10
|
+
improvise the decision or graduation model; follow the signatures and decision
|
|
11
|
+
flow in the spec.
|
|
12
|
+
|
|
13
|
+
## Quick orientation
|
|
14
|
+
|
|
15
|
+
`warrantd` is a standalone, framework-agnostic trust-layer library: it decides
|
|
16
|
+
whether an agent action is **ALLOW**, **REQUIRE_APPROVAL**, or **BLOCK**, and
|
|
17
|
+
governs how an action class *earns* more autonomy over time.
|
|
18
|
+
|
|
19
|
+
- It must **not** depend on or know about Slack, Stripe, Anthropic, OpenAI,
|
|
20
|
+
FastAPI, or any concrete transport/provider/store. Those belong in the
|
|
21
|
+
consuming app, which implements `MetricsProvider`, `ApprovalGate`, and
|
|
22
|
+
`AuditSink`.
|
|
23
|
+
- The graduation function is **pure and deterministic** — no LLM, no
|
|
24
|
+
randomness — and must be unit-testable in isolation.
|
|
25
|
+
|
|
26
|
+
## Conventions
|
|
27
|
+
|
|
28
|
+
- Tooling: `uv`, `ruff`, `pytest`, `mypy --strict`; ship `py.typed`.
|
|
29
|
+
- Keep runtime deps to the stdlib where possible (this is a trust primitive).
|
|
30
|
+
- Coverage gate on `graduation.py` and `decision.py` — keep these near-100%.
|
|
31
|
+
|
|
32
|
+
See `warrantd-spec.md` for the full repo layout, milestones, and boundary
|
|
33
|
+
contract.
|
warrantd-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Moritz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
warrantd-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: warrantd
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A warrant daemon for agent actions — earned autonomy with an audit trail.
|
|
5
|
+
Project-URL: Homepage, https://github.com/moritzkazooba-wq/warrantd
|
|
6
|
+
Project-URL: Repository, https://github.com/moritzkazooba-wq/warrantd
|
|
7
|
+
Author: Moritz
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: agents,approval,audit,autonomy,guardrails,trust
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# warrantd
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/warrantd/)
|
|
25
|
+
[](https://pypi.org/project/warrantd/)
|
|
26
|
+
[](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml)
|
|
27
|
+
[](./LICENSE)
|
|
28
|
+
|
|
29
|
+
> A warrant daemon for agent actions — earned autonomy with an audit trail.
|
|
30
|
+
|
|
31
|
+
`warrantd` answers one question for an agent that wants to take an action:
|
|
32
|
+
**ALLOW, REQUIRE_APPROVAL, or BLOCK?** — and governs how an action class *earns*
|
|
33
|
+
more autonomy over time. It is a standalone, framework-agnostic trust primitive:
|
|
34
|
+
it knows nothing about Slack, Stripe, OpenAI, Anthropic, FastAPI, or any
|
|
35
|
+
transport/provider/store. Your app supplies those by implementing three small
|
|
36
|
+
protocols.
|
|
37
|
+
|
|
38
|
+
See [`warrantd-spec.md`](./warrantd-spec.md) for the authoritative design.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv add warrantd # or: pip install warrantd
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Define a policy
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from decimal import Decimal
|
|
50
|
+
from warrantd import (
|
|
51
|
+
ActionClass, AutonomyState, GraduationThresholds, RiskTier, TrustPolicy,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
policy = TrustPolicy(
|
|
55
|
+
actions={
|
|
56
|
+
"read_ledger": ActionClass(name="read_ledger", risk=RiskTier.READ),
|
|
57
|
+
"issue_refund": ActionClass(
|
|
58
|
+
name="issue_refund",
|
|
59
|
+
risk=RiskTier.REVERSIBLE_WRITE,
|
|
60
|
+
auto_cap=Decimal("100"), # auto-approve at/below this
|
|
61
|
+
hard_cap=Decimal("1000"), # never auto-approve above this
|
|
62
|
+
),
|
|
63
|
+
},
|
|
64
|
+
thresholds=GraduationThresholds(
|
|
65
|
+
pass_rate={AutonomyState.SUPERVISED: 0.80, AutonomyState.AUTONOMOUS: 0.95},
|
|
66
|
+
adversarial_pass_rate={AutonomyState.SUPERVISED: 0.70, AutonomyState.AUTONOMOUS: 0.90},
|
|
67
|
+
min_samples={AutonomyState.SUPERVISED: 50, AutonomyState.AUTONOMOUS: 200},
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Gate an action
|
|
73
|
+
|
|
74
|
+
Implement `MetricsProvider` and `AuditSink` (and optionally `ApprovalGate`),
|
|
75
|
+
then call `evaluate()` before every tool execution and `record()` after:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from warrantd import ActionRequest, TrustLayer, Verdict
|
|
79
|
+
|
|
80
|
+
trust = TrustLayer(policy=policy, metrics=my_metrics, audit=my_audit)
|
|
81
|
+
|
|
82
|
+
decision = trust.evaluate(ActionRequest("issue_refund", tenant_id="acme", value=Decimal("250")))
|
|
83
|
+
if decision.verdict is Verdict.ALLOW:
|
|
84
|
+
... # execute
|
|
85
|
+
elif decision.verdict is Verdict.REQUIRE_APPROVAL:
|
|
86
|
+
... # route to your ApprovalGate
|
|
87
|
+
else:
|
|
88
|
+
... # BLOCK
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
A runnable end-to-end example with in-memory stubs lives in
|
|
92
|
+
[`examples/quickstart.py`](./examples/quickstart.py).
|
|
93
|
+
|
|
94
|
+
## How autonomy is earned
|
|
95
|
+
|
|
96
|
+
Each action class advances `MANUAL → SUPERVISED → AUTONOMOUS` only when its eval
|
|
97
|
+
metrics clear the thresholds for the target state, subject to a per-class policy
|
|
98
|
+
ceiling (`max_state`) and a risk ceiling for `CONSEQUENTIAL` actions. The
|
|
99
|
+
graduation function is pure and deterministic — no LLM, no randomness — so the
|
|
100
|
+
same metrics always yield the same allowed state.
|
|
101
|
+
|
|
102
|
+
## Documentation
|
|
103
|
+
|
|
104
|
+
A comprehensive, self-contained reference lives at
|
|
105
|
+
[`docs/warrantd-notebooklm.md`](./docs/warrantd-notebooklm.md). It explains the
|
|
106
|
+
concepts, the graduation model, the decision flow, the full API, worked
|
|
107
|
+
examples, a glossary, and an FAQ in prose form — written to be dropped into
|
|
108
|
+
NotebookLM (or any RAG system) as a single knowledge source.
|
|
109
|
+
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
uv sync --all-extras --dev
|
|
114
|
+
uv run ruff check .
|
|
115
|
+
uv run mypy --strict warrantd
|
|
116
|
+
uv run pytest --cov=warrantd
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Releasing
|
|
120
|
+
|
|
121
|
+
Releases publish to PyPI via [OIDC trusted publishing][tp] — no API tokens are
|
|
122
|
+
stored. One-time setup: register the `warrantd` trusted publisher on PyPI
|
|
123
|
+
(repo `moritzkazooba-wq/warrantd`, workflow `release.yml`, environment `pypi`).
|
|
124
|
+
Then:
|
|
125
|
+
|
|
126
|
+
1. Bump the version in `pyproject.toml` and `warrantd/__init__.py`, update
|
|
127
|
+
`CHANGELOG.md`, and tag (`vX.Y.Z`).
|
|
128
|
+
2. (Optional) Run the **release** workflow manually with target `testpypi` to
|
|
129
|
+
rehearse the upload.
|
|
130
|
+
3. Cut a GitHub Release — the workflow builds, runs `twine check`, and publishes
|
|
131
|
+
to PyPI.
|
|
132
|
+
|
|
133
|
+
[tp]: https://docs.pypi.org/trusted-publishers/
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT — see [LICENSE](./LICENSE).
|
warrantd-0.1.0/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# warrantd
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/warrantd/)
|
|
4
|
+
[](https://pypi.org/project/warrantd/)
|
|
5
|
+
[](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
> A warrant daemon for agent actions — earned autonomy with an audit trail.
|
|
9
|
+
|
|
10
|
+
`warrantd` answers one question for an agent that wants to take an action:
|
|
11
|
+
**ALLOW, REQUIRE_APPROVAL, or BLOCK?** — and governs how an action class *earns*
|
|
12
|
+
more autonomy over time. It is a standalone, framework-agnostic trust primitive:
|
|
13
|
+
it knows nothing about Slack, Stripe, OpenAI, Anthropic, FastAPI, or any
|
|
14
|
+
transport/provider/store. Your app supplies those by implementing three small
|
|
15
|
+
protocols.
|
|
16
|
+
|
|
17
|
+
See [`warrantd-spec.md`](./warrantd-spec.md) for the authoritative design.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add warrantd # or: pip install warrantd
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Define a policy
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from decimal import Decimal
|
|
29
|
+
from warrantd import (
|
|
30
|
+
ActionClass, AutonomyState, GraduationThresholds, RiskTier, TrustPolicy,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
policy = TrustPolicy(
|
|
34
|
+
actions={
|
|
35
|
+
"read_ledger": ActionClass(name="read_ledger", risk=RiskTier.READ),
|
|
36
|
+
"issue_refund": ActionClass(
|
|
37
|
+
name="issue_refund",
|
|
38
|
+
risk=RiskTier.REVERSIBLE_WRITE,
|
|
39
|
+
auto_cap=Decimal("100"), # auto-approve at/below this
|
|
40
|
+
hard_cap=Decimal("1000"), # never auto-approve above this
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
thresholds=GraduationThresholds(
|
|
44
|
+
pass_rate={AutonomyState.SUPERVISED: 0.80, AutonomyState.AUTONOMOUS: 0.95},
|
|
45
|
+
adversarial_pass_rate={AutonomyState.SUPERVISED: 0.70, AutonomyState.AUTONOMOUS: 0.90},
|
|
46
|
+
min_samples={AutonomyState.SUPERVISED: 50, AutonomyState.AUTONOMOUS: 200},
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Gate an action
|
|
52
|
+
|
|
53
|
+
Implement `MetricsProvider` and `AuditSink` (and optionally `ApprovalGate`),
|
|
54
|
+
then call `evaluate()` before every tool execution and `record()` after:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from warrantd import ActionRequest, TrustLayer, Verdict
|
|
58
|
+
|
|
59
|
+
trust = TrustLayer(policy=policy, metrics=my_metrics, audit=my_audit)
|
|
60
|
+
|
|
61
|
+
decision = trust.evaluate(ActionRequest("issue_refund", tenant_id="acme", value=Decimal("250")))
|
|
62
|
+
if decision.verdict is Verdict.ALLOW:
|
|
63
|
+
... # execute
|
|
64
|
+
elif decision.verdict is Verdict.REQUIRE_APPROVAL:
|
|
65
|
+
... # route to your ApprovalGate
|
|
66
|
+
else:
|
|
67
|
+
... # BLOCK
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
A runnable end-to-end example with in-memory stubs lives in
|
|
71
|
+
[`examples/quickstart.py`](./examples/quickstart.py).
|
|
72
|
+
|
|
73
|
+
## How autonomy is earned
|
|
74
|
+
|
|
75
|
+
Each action class advances `MANUAL → SUPERVISED → AUTONOMOUS` only when its eval
|
|
76
|
+
metrics clear the thresholds for the target state, subject to a per-class policy
|
|
77
|
+
ceiling (`max_state`) and a risk ceiling for `CONSEQUENTIAL` actions. The
|
|
78
|
+
graduation function is pure and deterministic — no LLM, no randomness — so the
|
|
79
|
+
same metrics always yield the same allowed state.
|
|
80
|
+
|
|
81
|
+
## Documentation
|
|
82
|
+
|
|
83
|
+
A comprehensive, self-contained reference lives at
|
|
84
|
+
[`docs/warrantd-notebooklm.md`](./docs/warrantd-notebooklm.md). It explains the
|
|
85
|
+
concepts, the graduation model, the decision flow, the full API, worked
|
|
86
|
+
examples, a glossary, and an FAQ in prose form — written to be dropped into
|
|
87
|
+
NotebookLM (or any RAG system) as a single knowledge source.
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
uv sync --all-extras --dev
|
|
93
|
+
uv run ruff check .
|
|
94
|
+
uv run mypy --strict warrantd
|
|
95
|
+
uv run pytest --cov=warrantd
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Releasing
|
|
99
|
+
|
|
100
|
+
Releases publish to PyPI via [OIDC trusted publishing][tp] — no API tokens are
|
|
101
|
+
stored. One-time setup: register the `warrantd` trusted publisher on PyPI
|
|
102
|
+
(repo `moritzkazooba-wq/warrantd`, workflow `release.yml`, environment `pypi`).
|
|
103
|
+
Then:
|
|
104
|
+
|
|
105
|
+
1. Bump the version in `pyproject.toml` and `warrantd/__init__.py`, update
|
|
106
|
+
`CHANGELOG.md`, and tag (`vX.Y.Z`).
|
|
107
|
+
2. (Optional) Run the **release** workflow manually with target `testpypi` to
|
|
108
|
+
rehearse the upload.
|
|
109
|
+
3. Cut a GitHub Release — the workflow builds, runs `twine check`, and publishes
|
|
110
|
+
to PyPI.
|
|
111
|
+
|
|
112
|
+
[tp]: https://docs.pypi.org/trusted-publishers/
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
MIT — see [LICENSE](./LICENSE).
|