Metadata-Version: 2.4
Name: provena
Version: 0.13.0
Summary: Context governance for agentic AI — tamper-evident audit trails for LLM context inputs
Project-URL: Homepage, https://github.com/rajfirke/provena
Project-URL: Documentation, https://rajfirke.github.io/provena
Project-URL: Source, https://github.com/rajfirke/provena
Project-URL: Issues, https://github.com/rajfirke/provena/issues
Author: Raj Firke
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agentic,ai,audit,context,eu-ai-act,governance,llm,owasp,provenance
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
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 :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: tomli>=2.0; python_version < '3.11'
Provides-Extra: all
Requires-Dist: click>=8.0; extra == 'all'
Requires-Dist: opentelemetry-api>=1.20; extra == 'all'
Requires-Dist: pyyaml>=6.0; extra == 'all'
Requires-Dist: rich>=13.0; extra == 'all'
Provides-Extra: autogen
Requires-Dist: autogen-agentchat>=0.4; extra == 'autogen'
Provides-Extra: cli
Requires-Dist: click>=8.0; extra == 'cli'
Requires-Dist: rich>=13.0; extra == 'cli'
Provides-Extra: crewai
Requires-Dist: crewai>=0.80; extra == 'crewai'
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-gen-files>=0.5; extra == 'docs'
Requires-Dist: mkdocs-literate-nav>=0.6; extra == 'docs'
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocs-section-index>=0.3; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
Provides-Extra: google-adk
Requires-Dist: google-adk>=1.0; extra == 'google-adk'
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.2; extra == 'langchain'
Provides-Extra: llamaindex
Requires-Dist: llama-index-core>=0.10; extra == 'llamaindex'
Provides-Extra: mcp
Requires-Dist: fastmcp>=2.0; extra == 'mcp'
Provides-Extra: openai-agents
Requires-Dist: openai-agents>=0.1; extra == 'openai-agents'
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.20; extra == 'otel'
Provides-Extra: postgres
Requires-Dist: psycopg[pool]>=3.1; extra == 'postgres'
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
Description-Content-Type: text/markdown

# Provena

[![CI](https://github.com/rajfirke/provena/actions/workflows/ci.yml/badge.svg)](https://github.com/rajfirke/provena/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/provena)](https://pypi.org/project/provena/)
[![Downloads](https://img.shields.io/pypi/dm/provena)](https://pypi.org/project/provena/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-green.svg)](LICENSE)
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)

**Context governance for agentic AI systems.** (MVP)

Your AI agent just made a decision based on data from 6 different sources.
Can you tell me which ones? Can you prove the data wasn't tampered with?
Can you verify it was still current?

Provena adds tamper-evident audit trails to any AI agent's context pipeline — in 3 lines of Python.

```python
from provena import ContextTrail

trail = ContextTrail()

@trail.track(source="retriever")
def search(query):
    return retriever.search(query)
```

Every call to `search()` is now logged with a SHA-256 content hash, provenance validation,
and a hash-chained audit trail that detects tampering.

## Why Provena?

> **AGT governs what agents DO. Guardrails AI governs what agents SAY. Provena governs what agents KNOW.**

No existing tool governs the context input layer. Provena fills this gap with:

- **Tamper-evident audit trails** — SHA-256 hash-chained (Merkle-style) logging with optional HMAC signing
- **Provenance validation** — Verify that context carries proper source metadata (VALID / MISSING / INCOMPLETE)
- **Freshness checking** — Detect stale context via metadata timestamps and regex temporal detection (FRESH / STALE / UNKNOWN)
- **Any context source** — RAG retrievers, tool outputs, agent messages, memory recalls, MCP resources
- **Sub-1ms overhead** — Pure Python, no ML models, no ONNX, no model downloads
- **Zero dependencies** — Core library uses only the Python standard library

## Install

```bash
pip install provena              # core (zero dependencies)
pip install provena[cli]         # + CLI tools (click, rich)
pip install provena[otel]        # + OpenTelemetry export
pip install provena[langchain]   # + LangChain adapter
pip install provena[llamaindex]  # + LlamaIndex adapter
pip install provena[all]         # everything
```

## Quick Start

```python
from provena import ContextTrail, ProvenanceMetadata
from datetime import datetime, timezone

trail = ContextTrail(storage_path="audit.db")

# Track any function that produces context
@trail.track(source="retriever")
def search(query):
    return retriever.search(query)

@trail.track(source="tool:pricing_api")
def get_price(product_id):
    return api.get(f"/price/{product_id}")

# Manual logging with provenance metadata
trail.log(
    content="The enterprise plan costs $499/month.",
    source="tool:pricing_api",
    provenance=ProvenanceMetadata(
        source_url="https://api.example.com/pricing",
        created_at=datetime.now(timezone.utc),
    ),
)

# Verify the audit trail hasn't been tampered with
verdict = trail.verify_chain()
print(f"Chain intact: {verdict.intact}")
print(f"Total records: {verdict.total_records}")
```

## CLI

Install with `pip install provena[cli]`, then:

```bash
# Verify hash chain integrity
provena --db audit.db verify
# PASS — Chain intact (42 records verified)

# Query the audit log
provena --db audit.db audit --source retriever --format json

# Generate a governance report
provena --db audit.db report --format text

# Quick summary
provena --db audit.db summary
```

For HMAC-signed trails, pass `--signing-key` or set `PROVENA_SIGNING_KEY`.

## Integrations

### LangChain

```python
from provena.integrations.langchain import ProvenaCallback

chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    callbacks=[ProvenaCallback(trail=trail)],
)
```

### LlamaIndex

```python
from provena.integrations.llamaindex import ProvenaPostprocessor

query_engine = index.as_query_engine(
    node_postprocessors=[ProvenaPostprocessor(trail=trail)]
)
```

### OpenTelemetry

```python
trail = ContextTrail(
    storage_path="audit.db",
    otel_enabled=True,
    otel_service_name="my-agent",
)
# Every log() call now emits an OTel span with governance attributes
```

## Architecture

```
Your Application
│
│  Retriever ──┐
│  Tool Call ──┤
│  Agent Msg ──┼──► ContextTrail ──► LLM Context Window
│  Memory    ──┤        │
│  MCP       ──┘        │
│                  ┌─────┴──────────────┐
│                  │ ProvenanceValidator │
│                  │ FreshnessChecker    │
│                  │ HashChain (SHA-256) │
│                  │ SQLite Backend      │
│                  │ OTel Exporter       │
│                  └────────────────────┘
```

## Compliance

Provena maps directly to EU AI Act requirements (enforcement: August 2, 2026):

| Article | Requirement | Provena Feature |
|---------|------------|-----------------|
| Art. 10 | Data lineage | Provenance validation for every context input |
| Art. 12 | Tamper-evident logging | SHA-256 hash-chained audit trail with HMAC signing |
| Art. 13 | Transparency | `trail.summary()` and source tracking |
| Art. 14 | Human oversight | `trail.annotate()` for reviewer decisions |

Also addresses **OWASP ASI06** (Memory & Context Poisoning).

## Contributing

We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, architecture guide, and PR process.

Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before participating.

## License

[Apache 2.0](LICENSE)
