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.
@@ -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
@@ -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.
@@ -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
+ [![PyPI version](https://img.shields.io/pypi/v/warrantd.svg)](https://pypi.org/project/warrantd/)
25
+ [![Python versions](https://img.shields.io/pypi/pyversions/warrantd.svg)](https://pypi.org/project/warrantd/)
26
+ [![CI](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml/badge.svg)](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./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).
@@ -0,0 +1,116 @@
1
+ # warrantd
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/warrantd.svg)](https://pypi.org/project/warrantd/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/warrantd.svg)](https://pypi.org/project/warrantd/)
5
+ [![CI](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml/badge.svg)](https://github.com/moritzkazooba-wq/warrantd/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./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).