Metadata-Version: 2.4
Name: vda-witness
Version: 0.1.0
Summary: VDA Witness SDK — seal your AI agent's decisions into tamper-evident, Ed25519-signed, independently-verifiable evidence (EU AI Act Art. 12). Fail-open, zero-config. Part of the Verified Digital Agents (VDA) platform.
Project-URL: Homepage, https://getvda.ai
License: UNLICENSED
Keywords: agents,ai-governance,audit,ed25519,eu-ai-act,evidence,vda,witness
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# vda-witness (Python SDK)

Seal your AI agent's decisions into **tamper-evident, Ed25519-signed, independently-verifiable evidence** — the records EU AI Act **Article 12** requires. Part of the **Verified Digital Agents (VDA)** platform; **VDA Witness** is its evidence layer.

- **Fail-open**: sealing never raises and never blocks your agent.
- **Zero-config, zero-dependency**: one import, set `WITNESS_API_KEY`, standard library only.
- **Independently verifiable**: anyone can verify a record offline, without trusting VDA.

## ⚠️ Read this first — what you get out of the box (custody)

Out of the box, sealing goes to the hosted Witness service on the **custodial / ephemeral (test) tier**: records are **signed by the Witness service, not by a key you control**. Every such record honestly carries `custody: "custodial"` and says so in plain text.

**This is for building and testing.** It is **NOT customer-controlled signing** and is **NOT compliance-grade EU AI Act Article-12 evidence** — do not present ephemeral custodial records to an auditor as your own controlled evidence.

For compliance-grade evidence, use **customer-managed signing** — you control the private key, records carry `custody: "customer-managed"` ("customer-controlled signing"), and Witness never sees your key. That is the tier you put in front of an auditor.

| Tier | Who holds the key | Record label | Use for |
|------|-------------------|--------------|---------|
| **Custodial (default/ephemeral)** | Witness service | `custodial` | build & test |
| **Customer-managed** | You | `customer-managed` | compliance-grade evidence |

## Install

```bash
pip install vda-witness
```

## First seal (copy-paste — works as-is)

```python
from vda_witness import Witness

witness = Witness()  # reads WITNESS_API_KEY

witness.seal(
    decision={"agent": "Refund Agent", "inputs": {"amount_eur": 150},
              "verdict": "PASS", "reasoning": "<= 200 and account in good standing"},
    governing_rule={"ruleId": "refund.auto",
                    "ruleText": "Agents MAY auto-approve refunds up to EUR200 where the account is in good standing."},
)
```

## Decorate an existing agent (code unchanged beyond the decorator)

```python
@witness.witnessed(
    to_decision=lambda args, kwargs, result: {
        "agent": "Refund Agent", "inputs": kwargs,
        "verdict": result["verdict"], "reasoning": result["why"],
    },
    rule={"ruleId": "refund.auto", "ruleText": "Agents MAY auto-approve refunds up to EUR200 ..."},
)
def decide(**request):
    ...  # your agent, untouched — sealed automatically after it returns (fail-open, bounded)
```

## Framework adapters

```python
from vda_witness import witness_openai
witness_openai(client, witness, {"ruleId": "assistant.sop", "ruleText": "..."})  # seals each chat.completions.create
```
Anthropic, LangChain, CrewAI, and the Vercel AI SDK use the same wrap-and-seal pattern (`witness.witnessed(...)`); typed adapters ship per release.

## Verify (no auth — the trust proposition)

```python
witness.verify(record=my_record)   # {"ok": True} — and False if anything changed
```

## Options

`Witness(api_key=None, base_url="https://witness.getvda.ai", timeout=3.0, fire_and_forget=False, on_error=None)`. Set `fire_and_forget=True` for zero added latency (seal on a background thread).

Honest scope: Witness produces the **evidence** (Art. 12 record-keeping), not a compliance certificate. The Article 12 Evidence Report is generated from your sealed trail; Compliance Officer attestation makes it a regulatory artefact.
