aura-state 0.2.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.
- aura_state-0.2.0/.github/workflows/ci.yml +26 -0
- aura_state-0.2.0/.github/workflows/publish.yml +25 -0
- aura_state-0.2.0/.gitignore +15 -0
- aura_state-0.2.0/CONTRIBUTING.md +48 -0
- aura_state-0.2.0/LAUNCH.md +98 -0
- aura_state-0.2.0/LICENSE +21 -0
- aura_state-0.2.0/PKG-INFO +374 -0
- aura_state-0.2.0/PUBLISHING.md +85 -0
- aura_state-0.2.0/README.md +340 -0
- aura_state-0.2.0/aura_state/__init__.py +126 -0
- aura_state-0.2.0/aura_state/compiler/__init__.py +1 -0
- aura_state-0.2.0/aura_state/compiler/dspy_tuner.py +124 -0
- aura_state-0.2.0/aura_state/compiler/json_generator.py +69 -0
- aura_state-0.2.0/aura_state/compiler/schema_compiler.py +221 -0
- aura_state-0.2.0/aura_state/compiler/spec_compiler.py +252 -0
- aura_state-0.2.0/aura_state/consensus/__init__.py +0 -0
- aura_state-0.2.0/aura_state/consensus/auto_vote.py +56 -0
- aura_state-0.2.0/aura_state/core/__init__.py +0 -0
- aura_state-0.2.0/aura_state/core/adaptive_graph.py +123 -0
- aura_state-0.2.0/aura_state/core/engine.py +470 -0
- aura_state-0.2.0/aura_state/core/exceptions.py +11 -0
- aura_state-0.2.0/aura_state/core/providers.py +294 -0
- aura_state-0.2.0/aura_state/core/replan.py +223 -0
- aura_state-0.2.0/aura_state/core/verification_loop.py +232 -0
- aura_state-0.2.0/aura_state/execution/__init__.py +0 -0
- aura_state-0.2.0/aura_state/execution/sandbox.py +228 -0
- aura_state-0.2.0/aura_state/execution/tracer.py +116 -0
- aura_state-0.2.0/aura_state/loaders/__init__.py +0 -0
- aura_state-0.2.0/aura_state/loaders/json_graph.py +157 -0
- aura_state-0.2.0/aura_state/memory/__init__.py +0 -0
- aura_state-0.2.0/aura_state/memory/pruner.py +40 -0
- aura_state-0.2.0/aura_state/verification/__init__.py +0 -0
- aura_state-0.2.0/aura_state/verification/conformal.py +263 -0
- aura_state-0.2.0/aura_state/verification/pipeline_conformal.py +82 -0
- aura_state-0.2.0/aura_state/verification/proof_engine.py +358 -0
- aura_state-0.2.0/aura_state/verification/risk_control.py +112 -0
- aura_state-0.2.0/aura_state/verification/taint.py +214 -0
- aura_state-0.2.0/aura_state/verification/temporal_verifier.py +324 -0
- aura_state-0.2.0/docs/ALGORITHMS.md +187 -0
- aura_state-0.2.0/docs/GUIDE.md +413 -0
- aura_state-0.2.0/examples/benchmark/README.md +35 -0
- aura_state-0.2.0/examples/benchmark/dataset.py +191 -0
- aura_state-0.2.0/examples/benchmark/nodes.py +108 -0
- aura_state-0.2.0/examples/benchmark/run_benchmark.py +290 -0
- aura_state-0.2.0/examples/benchmark/run_live.py +354 -0
- aura_state-0.2.0/examples/emit_contract_demo.py +81 -0
- aura_state-0.2.0/examples/pasc_demo.py +57 -0
- aura_state-0.2.0/examples/replan_demo.py +82 -0
- aura_state-0.2.0/examples/risk_abstention_demo.py +92 -0
- aura_state-0.2.0/examples/taint_proof_demo.py +87 -0
- aura_state-0.2.0/examples/verified_loop_demo.py +116 -0
- aura_state-0.2.0/pyproject.toml +49 -0
- aura_state-0.2.0/tests/test_bugsweep_fixes_0007.py +114 -0
- aura_state-0.2.0/tests/test_conformal_fixes_0004.py +167 -0
- aura_state-0.2.0/tests/test_ctl_fixes_0005.py +111 -0
- aura_state-0.2.0/tests/test_field_taint_fixes_0014.py +151 -0
- aura_state-0.2.0/tests/test_innovations.py +268 -0
- aura_state-0.2.0/tests/test_pasc_fixes_0011.py +68 -0
- aura_state-0.2.0/tests/test_phase9.py +248 -0
- aura_state-0.2.0/tests/test_proof_symbolic_fixes_0002.py +70 -0
- aura_state-0.2.0/tests/test_replan_fixes_0013.py +109 -0
- aura_state-0.2.0/tests/test_risk_control_fixes_0012.py +93 -0
- aura_state-0.2.0/tests/test_router.py +140 -0
- aura_state-0.2.0/tests/test_router_fixes_0006.py +76 -0
- aura_state-0.2.0/tests/test_sandbox_fixes_0001.py +75 -0
- aura_state-0.2.0/tests/test_spec_compiler_fixes_0015.py +109 -0
- aura_state-0.2.0/tests/test_taint_fixes_0014.py +83 -0
- aura_state-0.2.0/tests/test_tracer_fixes_0003.py +72 -0
- aura_state-0.2.0/tests/test_verified_loop.py +112 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
- name: Install
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
- name: Run tests
|
|
26
|
+
run: python -m pytest tests/ -q
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI automatically when you create a GitHub Release.
|
|
4
|
+
# Uses Trusted Publishing (OIDC) — no API token or password needed.
|
|
5
|
+
on:
|
|
6
|
+
release:
|
|
7
|
+
types: [published]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
environment: pypi # must match the Environment name on PyPI's pending publisher
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # required for Trusted Publishing (OIDC)
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- name: Build sdist + wheel
|
|
21
|
+
run: |
|
|
22
|
+
python -m pip install --upgrade build
|
|
23
|
+
python -m build
|
|
24
|
+
- name: Publish to PyPI
|
|
25
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Contributing to Aura-State
|
|
2
|
+
|
|
3
|
+
## Getting Started
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone <repo-url>
|
|
7
|
+
cd aura-state
|
|
8
|
+
pip install -e .
|
|
9
|
+
python -m pytest tests/ -v # 65 tests should pass
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Architecture
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
aura_state/
|
|
16
|
+
├── core/ → Engine, bandit router, health/edge metrics, verification loop, providers
|
|
17
|
+
├── compiler/ → Schema compiler, JSON generator, DSPy-inspired teleprompting
|
|
18
|
+
├── verification/ → Temporal verifier (CTL), conformal prediction, Z3 proof engine
|
|
19
|
+
├── execution/ → AuraTrace debugger, AST sandbox
|
|
20
|
+
├── memory/ → Context pruner
|
|
21
|
+
├── consensus/ → Multi-run extraction with voting
|
|
22
|
+
└── loaders/ → JSON/YAML graph loader
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Running Benchmarks
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Synthetic (no API key)
|
|
29
|
+
python examples/benchmark/run_benchmark.py
|
|
30
|
+
|
|
31
|
+
# Live (requires OPENAI_API_KEY in .env)
|
|
32
|
+
python examples/benchmark/run_live.py --model gpt-4o-mini --runs 3
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Pull Requests
|
|
36
|
+
|
|
37
|
+
1. Create a feature branch.
|
|
38
|
+
2. Write tests for your changes.
|
|
39
|
+
3. Ensure `python -m pytest tests/ -v` passes (all 65 tests).
|
|
40
|
+
4. Open a PR with a clear description of *what* and *why*.
|
|
41
|
+
|
|
42
|
+
## Design Principles
|
|
43
|
+
|
|
44
|
+
- Every feature uses a real algorithm, not an API wrapper.
|
|
45
|
+
- `AuraEngine` is the single entrypoint. All internals are always active.
|
|
46
|
+
- Math is executed in a sandboxed AST interpreter, never by the LLM.
|
|
47
|
+
- The DAG is the source of truth for state transitions.
|
|
48
|
+
- Formal verification happens *before* execution, not after.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Launch kit — Aura-State
|
|
2
|
+
|
|
3
|
+
Positioning: **dev-first**. Hero = developers building agents who are tired of "chain calls and hope."
|
|
4
|
+
One-liner: **Build LLM agents you can actually prove things about.**
|
|
5
|
+
Landing page: https://claude.ai/code/artifact/bff455f7-c4c5-44f5-8127-ba820fb9b6f6
|
|
6
|
+
|
|
7
|
+
Honesty guardrail for all copy: it's a real, correct core (Z3/CTL/conformal, adversarial tests) but **v0.2, early, OSS — not a hardened enterprise product.** Never claim battle-tested / production-proven. The defense against skeptics is that the tests run the actual solvers against adversarial inputs.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Product Hunt
|
|
12
|
+
|
|
13
|
+
**Name:** Aura-State
|
|
14
|
+
**Tagline (≤60 chars):** Build LLM agents you can prove things about
|
|
15
|
+
**Alt taglines:**
|
|
16
|
+
- Verification for AI agents that runs in the loop, not the sidebar
|
|
17
|
+
- Formal proofs for your agents — Z3, model checking, no API key to try
|
|
18
|
+
|
|
19
|
+
**Description (~260 chars):**
|
|
20
|
+
Most agent frameworks let you chain LLM calls and hope. Aura-State runs your workflow as a typed state machine and verifies every step in the loop — Z3 proves extracted data, CTL model-checks the graph, taint analysis makes it injection-proof, and conformal risk control decides when to escalate to a human. Open source, MIT, five runnable demos with no API key.
|
|
21
|
+
|
|
22
|
+
**First comment (maker):**
|
|
23
|
+
Hi PH 👋 I built Aura-State because "the agent verifier" in most stacks is either an assertion, an LLM judging another LLM, or a test suite that runs after the fact — none of which is a guarantee.
|
|
24
|
+
|
|
25
|
+
Aura-State moves verification *into* the loop:
|
|
26
|
+
- **Z3** proves each extraction against your obligations (`total == area * rate`); a hallucinated value is rejected with the counterexample, not passed downstream.
|
|
27
|
+
- **CTL model checking** proves reachability/completion/ordering over the whole graph before it runs.
|
|
28
|
+
- **Static taint** proves untrusted input can't reach a dangerous tool — injection-proof by construction, tracking provenance not content.
|
|
29
|
+
- **Conformal Risk Control** calibrates a threshold so the false-action rate is provably ≤ ε, else it escalates to a human.
|
|
30
|
+
- And the verifier **repairs the plan** from its own counterexamples, then compiles everything into a portable contract.
|
|
31
|
+
|
|
32
|
+
It's early (v0.2) and open source. Every guarantee is a demo you can run in ~10s with no API key, and the tests run the real solvers against adversarial inputs. Would love feedback from anyone building agents in high-stakes domains. Repo: github.com/munshi007/Aura-State
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Show HN
|
|
37
|
+
|
|
38
|
+
**Title:** Show HN: Aura-State – Verify LLM agents in the loop with Z3, CTL, and conformal prediction
|
|
39
|
+
|
|
40
|
+
**Body:**
|
|
41
|
+
Aura-State is a Python framework that runs an LLM agent as a typed state machine and verifies every step *in the loop* rather than beside it.
|
|
42
|
+
|
|
43
|
+
Concretely: a node declares proof obligations (`total == area * rate`) and they're checked with Z3 inside the extract→verify→retry loop — a value that can't be proven is rejected with the counterexample, not accepted. The workflow graph is model-checked with CTL (reachability, completion, ordering) at the init state. A static taint pass over the graph proves untrusted input can't reach a dangerous sink (injection-proof by construction — provenance, not content). Conformal Risk Control calibrates an act/abstain threshold with a finite-sample bound on the false-action rate. And counterexamples from any of these feed a replanner that repairs the design and re-verifies.
|
|
44
|
+
|
|
45
|
+
Why I built it: the "verification" in most agent stacks is an assertion, an LLM-judge, or a post-hoc eval — none of which is a guarantee, and the judge is itself unverifiable. I wanted the check to be a solver.
|
|
46
|
+
|
|
47
|
+
It's v0.2 and early. What I care most about getting right is correctness of the primitives, so the tests run the actual solvers against adversarial inputs (the classic `__subclasses__` sandbox escape, a wrong extraction, a genuine dead-end, empirical conformal coverage). Five demos run with no API key.
|
|
48
|
+
|
|
49
|
+
Repo (MIT): https://github.com/munshi007/Aura-State
|
|
50
|
+
Happy to go deep on the CTL init-state handling, the fail-closed AST→Z3 compiler, or the jackknife+ conformal — those are the parts people usually get subtly wrong.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## YC application answers
|
|
55
|
+
|
|
56
|
+
**What does your company do? (one line)**
|
|
57
|
+
Aura-State is an open-source framework that lets developers build LLM agents with formal guarantees — Z3 proofs, model checking, and calibrated risk control run inside the agent's loop.
|
|
58
|
+
|
|
59
|
+
**What is it, longer:**
|
|
60
|
+
Agents are moving into decisions where being wrong is expensive, but the tooling to *prove* an agent behaved is missing — teams rely on assertions, LLM-judges, and eval suites, which are heuristics, not guarantees. Aura-State runs the agent as a typed state machine and verifies each step with real solvers: Z3 for data obligations, CTL model checking for the graph, static taint for injection-safety, and conformal risk control for calibrated abstention. The design compiles into a portable, faithful-by-construction contract that a runtime can enforce.
|
|
61
|
+
|
|
62
|
+
**Why now?**
|
|
63
|
+
Three things converged in 2026: agents are being deployed into regulated, high-stakes workflows; the EU AI Act's high-risk obligations (traceability, human oversight) took effect; and the research on formal methods for LLM agents matured (CaMeL, AgentSpec, VeriGuard, conformal risk control). The verification techniques are proven; nobody has packaged them into a framework developers actually build in.
|
|
64
|
+
|
|
65
|
+
**Why us / why this is defensible?**
|
|
66
|
+
The moat isn't the orchestration — it's getting the verification primitives *correct*. Most "LLM verification" projects ship subtly wrong math (interpolated conformal quantiles, reversed CTL, fail-open provers). Aura-State's are correct and adversarially tested, and the design→contract compiler makes the spec faithful by construction — killing the "who writes and maintains the policy" problem every competitor concedes.
|
|
67
|
+
|
|
68
|
+
**Traction / status:** v0.2 open source, 117 tests, five runnable demos. Pre-launch.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Launch tweet / thread
|
|
73
|
+
|
|
74
|
+
**Tweet 1:**
|
|
75
|
+
Most agent frameworks: chain LLM calls and hope.
|
|
76
|
+
|
|
77
|
+
Aura-State: run the agent as a state machine and *prove* each step.
|
|
78
|
+
|
|
79
|
+
Z3 rejects a hallucinated value in the loop. CTL model-checks the graph. Taint makes it injection-proof. Open source, no API key to try 🧵
|
|
80
|
+
|
|
81
|
+
**Tweet 2:**
|
|
82
|
+
The verifier isn't another LLM judging the first one — it's a solver.
|
|
83
|
+
|
|
84
|
+
A node declares `obligations = ["total == area * rate"]`. If the extraction can't be *proven* to satisfy it, it's rejected with the counterexample and retried. Fail-closed.
|
|
85
|
+
|
|
86
|
+
**Tweet 3:**
|
|
87
|
+
Injection-proof by construction: label a node `untrusted_source` and a tool `dangerous_sink`, and Aura-State statically proves untrusted data can't reach it — tracking provenance, not content, so encodings can't fool it.
|
|
88
|
+
|
|
89
|
+
Everyone else sells detection. This is impossibility.
|
|
90
|
+
|
|
91
|
+
**Tweet 4:**
|
|
92
|
+
"Knows when it doesn't know" — made real. Conformal Risk Control calibrates a threshold so the agent's false-action rate is provably ≤ 5%. Below it, it escalates to a human instead of guessing.
|
|
93
|
+
|
|
94
|
+
**Tweet 5:**
|
|
95
|
+
And when a check fails, the verifier *repairs the plan* from its own counterexample and re-verifies — then compiles the whole thing into a portable contract.
|
|
96
|
+
|
|
97
|
+
v0.2, MIT, 5 demos run in ~10s with no API key 👇
|
|
98
|
+
github.com/munshi007/Aura-State
|
aura_state-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rohan Munshi
|
|
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,374 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: aura-state
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Build LLM agents you can prove things about — Z3 proofs, CTL model checking, and conformal risk control, verified in the loop.
|
|
5
|
+
Project-URL: Homepage, https://github.com/munshi007/Aura-State
|
|
6
|
+
Project-URL: Repository, https://github.com/munshi007/Aura-State
|
|
7
|
+
Project-URL: Issues, https://github.com/munshi007/Aura-State/issues
|
|
8
|
+
Author: Rohan Munshi
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent-framework,agents,ai-safety,conformal-prediction,ctl,formal-verification,llm,model-checking,prompt-injection,smt,state-machine,z3
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: instructor>=1.3
|
|
23
|
+
Requires-Dist: networkx>=3.0
|
|
24
|
+
Requires-Dist: openai>=1.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0
|
|
26
|
+
Requires-Dist: pymodelchecking>=1.3
|
|
27
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: z3-solver>=4.12
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<h1 align="center">Aura-State</h1>
|
|
36
|
+
|
|
37
|
+
<p align="center"><b>Build LLM agents you can actually prove things about.</b></p>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
Verification that runs <i>in the loop</i>, not the sidebar — Z3 proofs, CTL model checking, and conformal risk control gate every step. A value that can't be proven is never accepted.
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<img alt="CI" src="https://github.com/munshi007/Aura-State/actions/workflows/ci.yml/badge.svg">
|
|
45
|
+
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-3d3aa8.svg">
|
|
46
|
+
<img alt="Python" src="https://img.shields.io/badge/python-3.10%2B-blue.svg">
|
|
47
|
+
<img alt="tests" src="https://img.shields.io/badge/tests-130%20passing-1c8a5b.svg">
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install aura-state
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## See it in 10 seconds (no API key)
|
|
55
|
+
|
|
56
|
+
Every guarantee ships as a runnable proof against the real solvers:
|
|
57
|
+
|
|
58
|
+
| Demo | What it proves |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `python examples/verified_loop_demo.py` | Z3 rejects a hallucinated extraction in the loop, retries, accepts |
|
|
61
|
+
| `python examples/taint_proof_demo.py` | untrusted input provably can't reach a dangerous tool |
|
|
62
|
+
| `python examples/risk_abstention_demo.py` | acts only within a calibrated risk budget, else escalates to a human |
|
|
63
|
+
| `python examples/emit_contract_demo.py` | a portable contract compiled faithfully from the design |
|
|
64
|
+
| `python examples/replan_demo.py` | the verifier *repairs* the plan until it's proven-safe |
|
|
65
|
+
| `python examples/pasc_demo.py` | pipeline-aware conformal calibrates the end-to-end answer, not just each step |
|
|
66
|
+
|
|
67
|
+
## What this is
|
|
68
|
+
|
|
69
|
+
Most LLM frameworks let you chain API calls and hope for the best. Aura-State takes a different approach: you define your workflow as a typed graph of nodes, and **verification runs inside the loop** — every extraction must satisfy its formal contract before the workflow moves on.
|
|
70
|
+
|
|
71
|
+
The key difference is what happens between nodes:
|
|
72
|
+
|
|
73
|
+
- **Extractions** are checked against Z3 proof obligations, in the extract→verify→retry loop — a value that can't be proven is not accepted (fail-closed)
|
|
74
|
+
- **Math** runs in a no-`exec` sandboxed interpreter, never hallucinated
|
|
75
|
+
- **Uncertainty** is a real conformal interval over repeated runs, not a vibe
|
|
76
|
+
- **Workflows** are model-checked (CTL) for reachability/completion/ordering *before* they run
|
|
77
|
+
- **Routing** (when a node returns an ambiguous edge) is a Thompson-sampling bandit, not an LLM guess
|
|
78
|
+
|
|
79
|
+
## Quick example
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from aura_state import AuraEngine, Node, CompiledTransition
|
|
83
|
+
from pydantic import BaseModel, Field
|
|
84
|
+
from openai import OpenAI
|
|
85
|
+
|
|
86
|
+
# Define what you want to extract
|
|
87
|
+
class LeadData(BaseModel):
|
|
88
|
+
name: str = Field(description="Full name")
|
|
89
|
+
budget: int = Field(description="Budget in USD")
|
|
90
|
+
timeline: str = Field(description="Buying timeline")
|
|
91
|
+
|
|
92
|
+
# Define a node that extracts it — with a Z3 obligation the value must satisfy
|
|
93
|
+
class ExtractLead(Node):
|
|
94
|
+
system_prompt = "Extract lead info from a sales call transcript."
|
|
95
|
+
extracts = LeadData
|
|
96
|
+
obligations = ["budget > 0"] # proven in the loop; unprovable -> not accepted
|
|
97
|
+
|
|
98
|
+
def handle(self, user_text, extracted_data=None, memory=None):
|
|
99
|
+
return "QualifyBudget", extracted_data.model_dump()
|
|
100
|
+
|
|
101
|
+
# Define a decision node that does deterministic math (no LLM). Its rule runs
|
|
102
|
+
# even though the node does no extraction — it reads prior state from memory.
|
|
103
|
+
class QualifyBudget(Node):
|
|
104
|
+
system_prompt = "Score the lead."
|
|
105
|
+
sandbox_rule = "result = budget > 100000" # runs in the no-exec sandbox
|
|
106
|
+
|
|
107
|
+
def handle(self, user_text, extracted_data=None, memory=None):
|
|
108
|
+
return "END", memory
|
|
109
|
+
|
|
110
|
+
# Wire it up
|
|
111
|
+
engine = AuraEngine(llm_client=OpenAI())
|
|
112
|
+
engine.register(ExtractLead, QualifyBudget)
|
|
113
|
+
engine.connect([
|
|
114
|
+
CompiledTransition(from_node=ExtractLead, to_node=QualifyBudget),
|
|
115
|
+
])
|
|
116
|
+
|
|
117
|
+
# Run
|
|
118
|
+
next_state, data = engine.process("ExtractLead", user_text="Hi, I'm Sarah. Budget is $450k.")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## What happens under the hood
|
|
122
|
+
|
|
123
|
+
When you call `engine.process()`, it runs through these steps in order:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
1. Few-shot injection → optional: inject similar past successes as examples.
|
|
127
|
+
2. Verification loop → extract → check (sandbox rule + Z3 obligations) → retry.
|
|
128
|
+
A value that fails its contract is not accepted (fail-closed).
|
|
129
|
+
3. Conformal interval → with consensus > 1, build a real interval over the runs.
|
|
130
|
+
4. Your handle() method → your routing / business logic runs here.
|
|
131
|
+
5. Bandit router → if handle() returns an invalid edge, Thompson-sample a feasible one.
|
|
132
|
+
6. State serialization → save state (JSON, tamper-evident) for time-travel debugging.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Graph-level properties (reachability, completion, ordering) are checked separately
|
|
136
|
+
at **design time** with `engine.verify([...])` — CTL model checking over the whole
|
|
137
|
+
graph, which per-transition checks can't do. Everything above happens *in the loop*;
|
|
138
|
+
`engine.verification_reports()` returns the proof results and intervals per step.
|
|
139
|
+
|
|
140
|
+
## Formal verification (the interesting part)
|
|
141
|
+
|
|
142
|
+
This is what actually makes Aura-State different from other frameworks.
|
|
143
|
+
|
|
144
|
+
### Verify your workflow graph before it runs
|
|
145
|
+
|
|
146
|
+
Your node graph gets compiled into a [Kripke structure](https://en.wikipedia.org/wiki/Kripke_structure) and checked against temporal logic properties:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from aura_state import verify_engine, reachability, mutual_exclusion, eventual_completion
|
|
150
|
+
|
|
151
|
+
results = verify_engine(engine, [
|
|
152
|
+
{"description": "QualifyBudget is reachable", "formula": reachability("QualifyBudget")},
|
|
153
|
+
{"description": "All paths terminate", "formula": eventual_completion("QualifyBudget")},
|
|
154
|
+
])
|
|
155
|
+
# Result: PROVEN or VIOLATED, with the exact states that satisfy/violate
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
This is the same technique used to verify hardware circuits and flight control systems (CTL model checking, Clarke et al. 1986).
|
|
159
|
+
|
|
160
|
+
### Prove that extracted data is correct
|
|
161
|
+
|
|
162
|
+
After the LLM extracts values, Z3 (a theorem prover from Microsoft Research) can formally prove they satisfy your constraints:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from aura_state import prove_extraction
|
|
166
|
+
|
|
167
|
+
result = prove_extraction(
|
|
168
|
+
{"budget": 450000, "cost_per_sqft": 3, "total": 1350000},
|
|
169
|
+
obligations=["budget > 0", "total == budget * cost_per_sqft"],
|
|
170
|
+
)
|
|
171
|
+
# result.verified = True
|
|
172
|
+
# If False, Z3 gives you a counterexample showing exactly what broke
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
It also proves your obligations aren't *self-contradictory*. `["x > 5", "x < 3"]`
|
|
176
|
+
can never hold — Z3 catches that symbolically (variables ranging freely over the
|
|
177
|
+
declared field bounds, not pinned to one value), and the design→contract compiler
|
|
178
|
+
flags it per node before you ship.
|
|
179
|
+
|
|
180
|
+
### Confidence intervals on extractions
|
|
181
|
+
|
|
182
|
+
Run the extraction multiple times and get distribution-free confidence intervals:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from aura_state import conformal_interval
|
|
186
|
+
|
|
187
|
+
budgets = [450000, 452000, 448000, 450000, 451000]
|
|
188
|
+
ci = conformal_interval(budgets, confidence=0.95)
|
|
189
|
+
# ci.lower = 447800, ci.upper = 452200
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
This uses conformal prediction (Vovk et al., 2005) — no distributional assumptions required.
|
|
193
|
+
|
|
194
|
+
**Pipeline-aware (PASC):** a 95% guarantee at each node is *not* 95% end-to-end —
|
|
195
|
+
errors compound. `PipelineConformal` calibrates on the composed output so the
|
|
196
|
+
guarantee holds for the final answer. In the demo, per-step conformal covers the
|
|
197
|
+
end-to-end result only ~48%; PASC hits the nominal 90%. See
|
|
198
|
+
`python examples/pasc_demo.py`.
|
|
199
|
+
|
|
200
|
+
### Compile a runtime contract from the design
|
|
201
|
+
|
|
202
|
+
The obligations, CTL verdicts, and confidence a workflow was proven against
|
|
203
|
+
compile into a single portable, versioned contract. Because it's derived from
|
|
204
|
+
the same typed design the engine runs, the specification is **faithful by
|
|
205
|
+
construction** — spec and implementation are one artifact and can't drift.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
contract = engine.compile_contract(properties=[
|
|
209
|
+
{"description": "RouteLead is reachable", "formula": reachability("RouteLead")},
|
|
210
|
+
])
|
|
211
|
+
contract.to_json() # portable, content-addressable
|
|
212
|
+
check_faithfulness(contract, "QualifyLead", extracted) # contract agrees with the loop
|
|
213
|
+
diff_contracts(old, contract) # design-time regression gate
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Every other assurance system *consumes* a behavioral contract it can't author —
|
|
217
|
+
and hand-written policy drifts from the code (and is only 24–35% faithful when
|
|
218
|
+
translated from prose). Here the contract is emitted from the design that was
|
|
219
|
+
proven. See `python examples/emit_contract_demo.py`.
|
|
220
|
+
|
|
221
|
+
### Prove untrusted data can't reach a dangerous tool (injection-proof)
|
|
222
|
+
|
|
223
|
+
Label nodes with capability types and the compiler statically proves — over the
|
|
224
|
+
typed graph — that no untrusted source can reach a dangerous sink without
|
|
225
|
+
passing a sanitizer. It tracks *provenance, not content*, so it can't be fooled
|
|
226
|
+
by the encodings that defeat runtime scanners. The verdict compiles into the
|
|
227
|
+
contract, so a runtime can refuse to deploy a `VIOLATED` graph.
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
class Ingest(Node): untrusted_source = True # LLM / external tool output
|
|
231
|
+
class Review(Node): sanitizer = True # clears taint
|
|
232
|
+
class SendEmail(Node): dangerous_sink = True # irreversible action
|
|
233
|
+
|
|
234
|
+
analyze_taint(engine) # -> VIOLATED (Ingest -> SendEmail) unless Review is in the path
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
It's **field-level**: label individual fields, and a clean field passes a sink
|
|
238
|
+
untouched while only a *tainted* field reaching it is a violation — with the exact
|
|
239
|
+
field and its origin named. A field-specific sanitizer clears just its field.
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
class Ingest(Node): untrusted_fields = ["note"] # free text is untrusted
|
|
243
|
+
class Send(Node): sink_fields = ["account_id"] # the action consumes account_id
|
|
244
|
+
|
|
245
|
+
analyze_field_taint(engine) # PROVEN — the tainted `note` never reaches the sink arg
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Everyone else sells injection *detection* (probabilistic). This is
|
|
249
|
+
*impossibility* over the design. See `python examples/taint_proof_demo.py`.
|
|
250
|
+
|
|
251
|
+
### Act only if calibrated risk ≤ ε, otherwise escalate
|
|
252
|
+
|
|
253
|
+
The "knows when it doesn't know" story made into an actual gate. Calibrate a
|
|
254
|
+
controller on a labeled set and the agent auto-acts only when its false-action
|
|
255
|
+
rate is provably within budget — everything below the threshold escalates to a
|
|
256
|
+
human, never a silent guess.
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
ctrl = RiskController(epsilon=0.05).calibrate(scores, correct) # false-action rate ≤ 5%
|
|
260
|
+
|
|
261
|
+
class Decide(Node):
|
|
262
|
+
risk_controller = ctrl
|
|
263
|
+
escalation_node = "HumanReview"
|
|
264
|
+
def risk_score(self, extracted_data=None, conformal=None, memory=None):
|
|
265
|
+
return confidence # in [0,1]
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Uses Conformal Risk Control (arXiv:2208.02814); Learn-Then-Test
|
|
269
|
+
(arXiv:2110.01052) for tuning several thresholds. Abstention is a first-class
|
|
270
|
+
engine outcome. See `python examples/risk_abstention_demo.py`.
|
|
271
|
+
|
|
272
|
+
### Let the verifier repair the plan (counterexample-guided replanning)
|
|
273
|
+
|
|
274
|
+
Verification is usually a gate that says VIOLATED and stops. Here the
|
|
275
|
+
counterexample — a tainted path, a CTL violating state, a Z3 assignment — is fed
|
|
276
|
+
back to a replanner, which edits the plan and re-verifies, until it's proven or a
|
|
277
|
+
budget is hit. The plan is provably correct *because* the verifier drove it there.
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
result = engine.repair() # verify → counterexample → repair → re-verify
|
|
281
|
+
result.verified # True: driven to PROVEN (e.g. a sanitizer inserted)
|
|
282
|
+
result.unresolved # if it aborts: the explicit remaining violations
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Never a silent pass — an unrepairable design aborts with the violation named.
|
|
286
|
+
Refs: PAT-Agent (arXiv:2509.23675), VERIMAP (arXiv:2510.17109). See
|
|
287
|
+
`python examples/replan_demo.py`.
|
|
288
|
+
|
|
289
|
+
## Benchmark results
|
|
290
|
+
|
|
291
|
+
We ran 10 real-estate sales transcripts through a 4-node pipeline using GPT-4o-mini (30 API calls total):
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
Field Accuracy
|
|
295
|
+
────────────── ──────────
|
|
296
|
+
name 100%
|
|
297
|
+
budget 100%
|
|
298
|
+
bedrooms 100%
|
|
299
|
+
pre_approved 90%
|
|
300
|
+
timeline 90%
|
|
301
|
+
city 80%
|
|
302
|
+
|
|
303
|
+
Temporal properties: 3/3 proven
|
|
304
|
+
Z3 proof obligations: 20/20 passed
|
|
305
|
+
Avg latency: 1.4s
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# See verification reject a hallucination in the loop — no API key needed
|
|
310
|
+
python examples/verified_loop_demo.py
|
|
311
|
+
|
|
312
|
+
# Full pipeline benchmark — no API key needed
|
|
313
|
+
python examples/benchmark/run_benchmark.py
|
|
314
|
+
|
|
315
|
+
# With real LLM calls (needs OPENAI_API_KEY in .env)
|
|
316
|
+
python examples/benchmark/run_live.py --model gpt-4o-mini --runs 3
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Project structure
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
aura_state/
|
|
323
|
+
├── core/
|
|
324
|
+
│ ├── engine.py # Main engine — verified process() loop + bandit router
|
|
325
|
+
│ ├── adaptive_graph.py # Node health metrics + per-edge Beta-Bernoulli posteriors
|
|
326
|
+
│ ├── verification_loop.py # Extract → verify (sandbox + Z3) → retry loop
|
|
327
|
+
│ └── providers.py # Multi-model routing + cost tracking
|
|
328
|
+
├── verification/ # ← the core: correct, adversarially-tested primitives
|
|
329
|
+
│ ├── proof_engine.py # Z3 proofs (fail-closed AST→Z3 compiler, no eval)
|
|
330
|
+
│ ├── conformal.py # jackknife+ prediction intervals (order statistic)
|
|
331
|
+
│ └── temporal_verifier.py # Kripke + CTL model checking (init-state, structural deadlocks)
|
|
332
|
+
├── execution/
|
|
333
|
+
│ ├── sandbox.py # No-exec allowlist AST evaluator (deny-by-default)
|
|
334
|
+
│ └── tracer.py # State serialization, tamper-evident JSON (time-travel debug)
|
|
335
|
+
├── compiler/
|
|
336
|
+
│ ├── schema_compiler.py # JSON Schema → Node classes
|
|
337
|
+
│ └── dspy_tuner.py # KNN few-shot selection (real embedder required)
|
|
338
|
+
├── memory/
|
|
339
|
+
│ └── pruner.py # Context window optimization
|
|
340
|
+
└── consensus/
|
|
341
|
+
└── auto_vote.py # Multi-run extraction with voting
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Installation
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
pip install aura-state
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Or the latest from source:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
pip install git+https://github.com/munshi007/Aura-State.git
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Python 3.10+ required. Dependencies: `pydantic`, `instructor`, `openai`, `networkx`, `pyModelChecking`, `z3-solver`, `pyyaml`.
|
|
357
|
+
|
|
358
|
+
## Tests
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
python -m pytest tests/ -v
|
|
362
|
+
# 100 tests passing
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Docs
|
|
366
|
+
|
|
367
|
+
- [Usage Guide](docs/GUIDE.md) — code examples for every feature
|
|
368
|
+
- [Algorithm Reference](docs/ALGORITHMS.md) — deep-dive into CTL, Z3, Thompson sampling, conformal prediction
|
|
369
|
+
- [Contributing](CONTRIBUTING.md) — architecture overview and how to contribute
|
|
370
|
+
- [Benchmark](examples/benchmark/) — synthetic and live benchmarks
|
|
371
|
+
|
|
372
|
+
## License
|
|
373
|
+
|
|
374
|
+
MIT
|