Metadata-Version: 2.4
Name: aga-governance
Version: 0.2.6
Summary: AGA Python SDK - Cryptographic governance receipts for AI agent tool calls
Project-URL: Homepage, https://attestedintelligence.com
Project-URL: Specification, https://attestedintelligence.com/spec
Project-URL: Verifier, https://attestedintelligence.com/verify
Author: Attested Intelligence Holdings LLC
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent,ai,cryptographic,governance,receipts
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.9
Requires-Dist: pynacl>=1.6.2
Description-Content-Type: text/markdown

# AGA Python SDK

Cryptographic governance receipts for AI agent tool calls. This SDK emits the
**canonical SEP evidence bundle**, the same offline-verifiable artifact the
AGA gateway produces, so a governance decision sealed in Python re-derives,
byte-for-byte, under the reference verifiers in three languages (JavaScript,
Go, Python): three separate implementations, runnable offline without the
producer.

PyPI distribution: `aga-governance`.

## What the SDK emits

Each governed tool call becomes a signed, 15-field governance receipt. Receipts
hash-link into an append-only chain, the chain's leaves bind into a Merkle root,
and a gateway-signed checkpoint binds the root, leaf count, and chain head so
truncation is detectable. The bundle uses standard primitives only:

- **Ed25519** receipt signatures (RFC 8032).
- **SHA-256** for hash chaining, Merkle trees, and leaf computation.
- **JCS-lineage canonicalization**: deterministic, byte-compatible with the
  reference verifier and with the TypeScript and Go implementations.
- A **no-prefix** binary Merkle tree with a **mandatory signed checkpoint**
  (the construction is frozen in the `aga-receipt-spec` repository).

## Install

```bash
pip install aga-governance
```

> Install `aga-governance` (the distribution name). The unrelated PyPI project
> named `aga` is a different package; installing it will not give you this SDK.

## Quick Start

```python
from aga import AgentSession

SEED = bytes.fromhex("cc" * 32)  # 32-byte signing seed (provision securely)

with AgentSession(gateway_id="my-gateway", signing_key_seed=SEED) as session:
    session.record_tool_call(
        tool_name="read_file",
        decision="PERMITTED",
        reason="allowed by policy",
        request_id="req-001",
    )
    bundle = session.export_bundle()      # a canonical SEP evidence bundle (dict)
    result = session.verify()
    assert result["overall_valid"]
```

## Verifying a bundle

Verification is producer-independent: any conformant verifier reaches the same
verdict on the same bundle, offline. Start with the Python-native paths this
package ships.

**CLI:**

```bash
aga verify bundle.json          # human-readable, check-by-check output
aga verify bundle.json --json   # the full result object as JSON
```

```text
Bundle: bundle.json
Algorithm: Ed25519-SHA256-JCS
Receipts checked: 2
  Algorithm valid:     True
  Signatures valid:    True
  Chain integrity:     True
  Merkle proofs:       True
  Bundle consistent:   True
  Checkpoint valid:    True
  Envelope consistent: True

Verification: PASSED (integrity only: issuer not verified; pass --pubkey to verify provenance)
```

**API:**

```python
import aga

result = aga.verify_bundle_file("bundle.json")
assert result["overall_valid"]
```

Pin the gateway public key to also prove *who* issued the bundle; without a
pinned key you get an integrity-only result:

```bash
aga verify bundle.json --pubkey <64-hex-gateway-public-key>
# -> Verification: PASSED (provenance verified)
```

```python
result = aga.verify_bundle_file("bundle.json", expected_public_key="<64-hex>")
```

### Cross-checking with the other reference verifiers

A Python-produced bundle verifies under the reference verifiers in three
languages (JavaScript, Go, and Python): three separate implementations,
runnable offline without the producer. The SDK's canonicalization and leaf
computation are pinned to the same cross-language conformance vectors, so a
bundle sealed here re-derives byte-for-byte under each. This SDK's verifier
enforces the same strict conformance rules (exact-key schema, canonical
timestamps and ordering, envelope consistency, strict-hex Merkle proofs, and a
mandatory signed checkpoint), so it agrees with them verdict-for-verdict
rather than being a looser convenience check.

#### Check-name mapping vs the JS reference verifier

The two stacks decompose the same seven-check verification differently. Overall
verdicts and exit codes agree on every conformance-corpus case (re-proven
2026-07-01: 10/10 cells across pristine/tampered bundles with unpinned, correct,
and wrong keys); the sub-check that reports a given tamper can differ:

| Python result field | JS reference check | What it covers |
|---|---|---|
| `algorithm_valid` (+ parts of `bundle_consistent`) | `structural` | algorithm id, key well-formedness, counts |
| `receipt_signatures_valid` | `receipt_signatures` | Ed25519 over canonical receipt bytes |
| `chain_integrity_valid` | `chain_and_ordering` | prev-leaf linkage, monotonic ids and timestamps |
| `merkle_proofs_valid` | `merkle_and_bijection` | leaf recompute, single-root walk, index bijection |
| `checkpoint_valid` | `signed_checkpoint` | gateway-signed root + count + chain-head binding |
| `envelope_consistent` | `envelope_consistency` | envelope metadata vs signed content |
| `gateway_key_match` / `provenance` | `gateway_key_match` (with `--pubkey`) | pinned issuer key |

Known decomposition difference: the JS reference recomputes every Merkle leaf
from full receipt content, so a receipt-signature tamper also fails its
`merkle_and_bijection`; this SDK surfaces the same tamper in
`receipt_signatures_valid`, `chain_integrity_valid`, and `bundle_consistent`
while `merkle_proofs_valid` can remain true. Neither is looser: the bundle
fails in both stacks, exit 1. A malformed `--pubkey` pin is a usage error
(exit 2) here, while the JS reference treats a malformed pin as unpinned; the
Python behavior is strictly tighter.

```bash
# JavaScript reference verifier, from the aga-receipt-spec repository
# (published with the npm package @attested-intelligence/aga-mcp-server on
# GitHub: https://github.com/attestedintelligence/aga-mcp-server):
node aga-receipt-spec/verify/verify-sep.mjs bundle.json --pubkey <gateway-public-key>
```

## Scope: what a verified bundle proves

A verified bundle proves the **integrity of the receipts present**: each is
authentic, correctly ordered, Merkle-included, and (when a key is pinned)
provenance-bound. It does **not** prove the policy was correct, and it does not
prove non-omission: completeness of capture is bounded by the tamper-evidence
of the interception point, which is outside the bundle. The offline-verifiable
artifact a counterparty receives is payload-excluded (it carries an
`arguments_hash`, never the raw payload). We prove the record, not that the
policy was correct.

## Tests

Our source repository carries the automated suite: 209 tests as of 2026-07-04
(`python -m pytest`), including the cross-stack conformance vectors that prove
byte-for-byte agreement with the JavaScript and Go implementations. The
published wheel and sdist ship the library only; the tests are not part of the
installed package.

## License

Apache-2.0. Patent Pending.
