Prove your AI followed the rules. With tamper-proof evidence. Three lines of code. Zero data retained. 135 procedures across 5 industry verticals.
Wrap your AI client. Every inference is witnessed automatically. Your response is untouched.
from swt3_ai import Witness from openai import OpenAI witness = Witness( endpoint="https://sovereign.tenova.io", api_key="axm_live_...", tenant_id="YOUR_ENCLAVE", ) client = witness.wrap(OpenAI()) # Every inference is now witnessed. Response is untouched. response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Hello"}], ) print(response.choices[0].message.content)
What happens per inference: Intercept > Hash prompt/response locally > Extract factors (model, latency, tokens, guardrails) > Clear raw data from wire > Anchor to SWT3 ledger in background > Return your response untouched.
| Provider | Python | TypeScript | Detection |
|---|---|---|---|
| OpenAI | v0.2.1 | v0.2.1 | Auto (openai module) |
| Anthropic | v0.2.1 | v0.2.1 | Auto (anthropic module) |
| AWS Bedrock | v0.2.1 | v0.2.1 | Auto (botocore/BedrockRuntimeClient) |
| Vercel AI SDK | N/A | v0.2.1 | onFinish callback |
| Ollama / vLLM | v0.2.1 | v0.2.1 | Via OpenAI-compatible client |
| Custom | v0.2.1 | v0.2.1 | @witness.inference() decorator / witness.record() |
client = witness.wrap(OpenAI()) response = client.chat.completions.create(model="gpt-4o", messages=[...])
client = witness.wrap(Anthropic()) message = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=1024, messages=[...])
import boto3 bedrock = boto3.client("bedrock-runtime", region_name="us-east-1") client = witness.wrap(bedrock) response = client.converse( modelId="anthropic.claude-3-5-sonnet-20241022-v2:0", messages=[{"role": "user", "content": [{"text": "Hello"}]}], )
# Ollama exposes an OpenAI-compatible API from openai import OpenAI client = witness.wrap(OpenAI(base_url="http://localhost:11434/v1")) response = client.chat.completions.create(model="llama3", messages=[...])
Clearing controls what leaves your infrastructure. Your code always gets the full response. Clearing only affects the wire payload sent to the witness ledger.
| Level | Name | On the Wire | Use Case |
|---|---|---|---|
| 0 | Analytics | Hashes + factors + model ID + provider + guardrails | Internal dashboards |
| 1 | Standard | Hashes + factors + model ID + provider | Default. Production SaaS |
| 2 | Sensitive | Hashes + factors + model ID only | Healthcare, legal, PII |
| 3 | Classified | Numeric factors only. Model ID hashed. | Defense, SCIF, air-gapped |
# Level 2: Healthcare / Legal - no provider names on wire witness = Witness( endpoint="...", api_key="axm_...", tenant_id="...", clearing_level=2, )
At Level 1+, raw prompts and responses never leave your infrastructure. Only SHA-256 hashes and numeric factors travel on the wire. This satisfies both GDPR Article 17 (right to erasure) and EU AI Act Article 12 (record-keeping) simultaneously.
| Parameter | Default | Description |
|---|---|---|
| endpoint | required | Witness endpoint URL |
| api_key / apiKey | required | API key (axm_* prefix) |
| tenant_id / tenantId | required | Your enclave identifier |
| clearing_level / clearingLevel | 1 | Clearing level (0-3) |
| buffer_size / bufferSize | 10 | Flush after N anchors |
| flush_interval / flushInterval | 5.0 | Flush after N seconds |
| timeout | 10.0 | HTTP timeout for flush |
| max_retries / maxRetries | 3 | Retry count before dead-letter |
| latency_threshold_ms | 30000 | AI-INF.2 latency threshold (ms) |
| guardrails_required | 0 | AI-GRD.1 required guardrail count |
| guardrail_names | [] | Names of active guardrails |
| factor_handoff / factorHandoff | None | Handoff method: "file" (webhook, vault, KMS planned) |
| factor_handoff_path / factorHandoffPath | None | Directory for handoff files (required when handoff="file") |
Each inference produces anchors for these procedures. Full factor definitions are in the UCT Registry.
| Procedure | Domain | What It Proves | EU AI Act |
|---|---|---|---|
| AI-INF.1 | Inference | Prompt and response were captured (provenance) | Art.12(1) |
| AI-INF.2 | Inference | Latency within threshold (detects model swaps) | Art.12(2) |
| AI-MDL.1 | Model | Deployed model matches approved identity | Art.13(3)(b) |
| AI-MDL.2 | Model | Model version identifier recorded | Art.12(2)(b) |
| AI-GRD.1 | Guardrail | Required safety filters were active | Art.15(3) |
| AI-GRD.2 | Safety | No refusal or content filter triggered | Art.15(3) |
17 AI procedures + 5 FinTech (SR 11-7) + 5 Construction (OSHA) + 3 Healthcare (HIPAA) = 135 total across 12 frameworks. View full catalog.
| Procedure | Domain | What It Proves | SR 11-7 |
|---|---|---|---|
| FIN-GOV.1 | Governance | Committee achieved quorum and approved model | Sec. III |
| FIN-MRM.1 | Inventory | Model hash matches approved inventory entry | Sec. V |
| FIN-VAL.1 | Validation | Independent validator confirmed model performance | Sec. VI |
| FIN-MON.1 | Monitoring | Performance metric within threshold (PSI, AUC) | Sec. VII |
| FIN-OUT.1 | Outcomes | Back-test sample adequate and within tolerance | Sec. VIII |
At Clearing Level 2 and above, factors are purged from the wire. The Factor Handoff protocol lets you retain full evidence custody on your own infrastructure by writing uncleared factor data to a local file before clearing proceeds.
Safety guarantee: The handoff writes factors BEFORE clearing. If the write fails, the payload is NOT transmitted. Evidence custody is preserved or nothing happens.
witness = Witness(
endpoint="...",
api_key="axm_...",
tenant_id="...",
clearing_level=2,
factor_handoff="file",
factor_handoff_path="/secure/handoff/",
)
Each inference produces a JSON file with the full uncleared data (factors + metadata). The file is written atomically (temp + rename) with 0600 permissions. Your infrastructure retains the evidence; Axiom only receives the cleared version.
Full protocol spec: Factor Handoff Protocol
# Decorator for custom inference functions @witness.inference() def my_pipeline(prompt: str) -> str: # Your custom logic return result # Or manual recording from swt3_ai.types import InferenceRecord from swt3_ai.fingerprint import sha256_truncated record = InferenceRecord( model_id="my-model-v2", model_hash=sha256_truncated("my-model-v2"), prompt_hash=sha256_truncated(prompt), response_hash=sha256_truncated(response), latency_ms=elapsed_ms, provider="custom", ) witness.record(record)
The SDK never blocks your inference. Witnessing happens in a background thread/microtask. If the endpoint is unreachable, payloads move to a dead-letter queue and drain automatically when connectivity is restored.
# Python: Check dead-letter status print(f"Pending: {witness.pending}") # Graceful shutdown (also happens at exit) receipts = witness.flush()
Axiom container images are scanned daily for vulnerabilities. Zero-critical-CVE policy enforced. All findings are automatically documented as POA&M entries with severity-based remediation timelines (CRITICAL: 7d, HIGH: 30d, MEDIUM: 90d). Scan results are self-anchored in the witness ledger (RA-5/SI-2).
Every anchor can be independently verified without an Axiom account.
# CLI $ axiom verify SWT3-E-CLOUD-AI-AI-INF.2-PASS-1774995559-a1b2c3d4e5f6 # Browser (zero server calls) sovereign.tenova.io/verify # Formula SHA256("WITNESS:{tenant}:{procedure}:{fa}:{fb}:{fc}:{ts_ms}")[0:12]