PAC-AI: Protocol for Auditable Context in AI — Python SDK
Project description
jhcontext SDK
PAC-AI: Protocol for Auditable Context in AI — Python SDK
A Python toolkit for building, signing, auditing, and serving AI context envelopes compliant with the PAC-AI protocol. Designed for EU AI Act compliance scenarios including temporal oversight (Art. 14) and negative proof (Art. 13).
Install
# Core: models, builder, PROV, audit, crypto
pip install jhcontext
# With server (FastAPI + MCP + SQLite)
pip install "jhcontext[server]"
# With CrewAI integration
pip install "jhcontext[crewai]"
# Everything
pip install "jhcontext[all]"
# Development (adds pytest)
pip install "jhcontext[all,dev]"
Architecture
jhcontext/
├── models.py # Pydantic v2 data models (Envelope, Artifact, Decision, ...)
├── builder.py # EnvelopeBuilder — fluent API for constructing envelopes
├── prov.py # PROVGraph — W3C PROV graph builder (rdflib)
├── audit.py # Compliance verification (temporal oversight, negative proof, isolation)
├── crypto.py # SHA-256 hashing, Ed25519 signing (HMAC fallback)
├── canonicalize.py # Deterministic JSON serialization
├── semantics.py # UserML semantic payload helpers
├── cli.py # CLI: jhcontext serve | mcp | version
├── client/
│ └── api_client.py # REST client (httpx)
└── server/
├── app.py # FastAPI app factory
├── mcp_server.py # MCP server (stdio transport)
├── routes/ # REST API routes (envelopes, artifacts, decisions, provenance, compliance)
└── storage/
└── sqlite.py # SQLite backend (zero-config, ~/.jhcontext/)
Quick Start
Build and sign an envelope
from jhcontext import EnvelopeBuilder, RiskLevel, ArtifactType, observation, userml_payload
# Build semantic payload
payload = userml_payload(
observations=[observation("user:alice", "temperature", 22.3)],
)
# Build envelope
env = (
EnvelopeBuilder()
.set_producer("did:example:agent-1")
.set_scope("healthcare")
.set_risk_level(RiskLevel.HIGH)
.set_human_oversight(True)
.set_semantic_payload([payload])
.add_artifact(
artifact_id="art-vitals",
artifact_type=ArtifactType.TOKEN_SEQUENCE,
content_hash="sha256:abc123...",
)
.sign("did:example:agent-1")
.build()
)
print(env.context_id)
print(env.proof.content_hash)
Build a W3C PROV graph
from jhcontext import PROVGraph
prov = (
PROVGraph("ctx-health-001")
.add_entity("vitals", "Patient Vitals", artifact_type="token_sequence")
.add_entity("recommendation", "AI Recommendation")
.add_activity("ai-analysis", "AI Analysis",
started_at="2026-01-01T10:00:00Z",
ended_at="2026-01-01T10:01:00Z")
.add_agent("agent-sensor", "Sensor Agent", role="data_collector")
.used("ai-analysis", "vitals")
.was_generated_by("recommendation", "ai-analysis")
.was_associated_with("ai-analysis", "agent-sensor")
.was_derived_from("recommendation", "vitals")
)
# Serialize
print(prov.serialize("turtle"))
# Query
chain = prov.get_causal_chain("recommendation")
used = prov.get_used_entities("ai-analysis")
sequence = prov.get_temporal_sequence()
Run compliance audits
from jhcontext import (
verify_temporal_oversight,
verify_negative_proof,
verify_workflow_isolation,
verify_integrity,
generate_audit_report,
)
# Art. 14 — Temporal oversight (human reviewed AFTER AI, >= 5 min)
result = verify_temporal_oversight(
prov,
ai_activity_id="ai-analysis",
human_activities=["doctor-review"],
min_review_seconds=300.0,
)
# Art. 13 — Negative proof (excluded data types not in decision chain)
result = verify_negative_proof(
prov,
decision_entity_id="final-grade",
excluded_artifact_types=["biometric", "social_media"],
)
# Workflow isolation (two PROV graphs share zero artifacts)
result = verify_workflow_isolation(prov_a, prov_b)
# Envelope integrity (hash + signature)
result = verify_integrity(env)
# Generate full audit report
report = generate_audit_report(env, prov, [result1, result2, result3])
print(report.to_dict())
Start the server
# REST API on localhost:8400
jhcontext serve
# MCP server (stdio transport)
jhcontext mcp
Use the REST client
from jhcontext.client.api_client import JHContextClient
client = JHContextClient(base_url="http://localhost:8400")
# Submit envelope
ctx_id = client.submit_envelope(env)
# Retrieve
data = client.get_envelope(ctx_id)
# List with filters
envelopes = client.list_envelopes(scope="healthcare")
# Health check
print(client.health())
client.close()
Testing
pip install -e ".[all,dev]"
pytest tests/ --ignore=tests/test_example.py -v
Key Concepts
| Concept | Description |
|---|---|
| Envelope | Immutable context unit: semantic payload + artifacts + provenance + proof |
| Artifact | Registered data object (embedding, token sequence, tool result) with content hash |
| PROVGraph | W3C PROV provenance graph (entities, activities, agents, relations) |
| Proof | Cryptographic integrity: canonical hash + Ed25519/HMAC signature |
| Audit | Compliance checks: temporal oversight, negative proof, workflow isolation |
| UserML | Semantic payload format: observation → interpretation → situation layers |
Protocol
Based on the PAC-AI (Protocol for Auditable Context in AI) specification. JSON-LD schema at jhcontext-protocol/jhcontext-core.jsonld (v0.3).
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jhcontext-0.2.3.tar.gz.
File metadata
- Download URL: jhcontext-0.2.3.tar.gz
- Upload date:
- Size: 31.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2d4168071f2ee62c439e8a45fb448f15b4364cf31e757dadf6515d1bbff3f60
|
|
| MD5 |
b77e95f03b14ff9dcc6b739663363c1c
|
|
| BLAKE2b-256 |
859d5f319bd6d6ccb625df9511ad52d3b749cadaf03c73c0da0908c9eae40bb6
|
File details
Details for the file jhcontext-0.2.3-py3-none-any.whl.
File metadata
- Download URL: jhcontext-0.2.3-py3-none-any.whl
- Upload date:
- Size: 29.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59310b33f475b22f7a97472952c50c348dcbea7e5bb5bafa1db93ac0c9cffdab
|
|
| MD5 |
6a6fd2be0666f0976e8ccec27e561bf3
|
|
| BLAKE2b-256 |
d578b1392a4ecdebc04960403c25ae843ba6ece81e68d5113aceb2b4485ab84e
|