# VVUQ-MCP API Examples & Use Cases
**Server:** https://vvuq.dirkenglund.org
**Interactive Docs:** https://vvuq.dirkenglund.org/docs
**Version:** see the live [`/health`](https://vvuq.dirkenglund.org/health) endpoint (derived from package metadata)
All examples tested and validated against the production API.
---
## Table of Contents
1. [Authentication](#authentication)
2. [Basic Workflow](#basic-workflow)
3. [Contract Creation Examples](#contract-creation-examples)
4. [Proof Submission Examples](#proof-submission-examples)
5. [Advanced Workflows](#advanced-workflows)
6. [Python Client Examples](#python-client-examples)
7. [Error Handling](#error-handling)
8. [Security & Rulesets](#security--rulesets)
9. [Z3 SMT Solver](#z3-smt-solver)
10. [Vision Figure Comparison](#vision-figure-comparison)
11. [Knowledge Graph Search](#knowledge-graph-search)
12. [Document Review (Compliance Checking)](#document-review-compliance-checking)
13. [Feedback & Support](#feedback--support)
---
## Authentication
VVUQ-MCP supports **two authentication formats** - use whichever your client prefers:
### Method 1: X-API-Key Header (Original)
```bash
curl -H "X-API-Key: YOUR_API_KEY" \
https://vvuq.dirkenglund.org/api/v1/contracts
```
### Method 2: Authorization: Bearer (Standard)
```bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://vvuq.dirkenglund.org/api/v1/contracts
```
### Example API Keys
```
Primary: vvuq_YOUR_KEY_HERE
Secondary: vvuq_YOUR_KEY_HERE
```
**Note:** Both formats work identically. Examples below use Bearer for clarity.
---
## Basic Workflow
### Complete Verification Flow (5 Steps)
```bash
# Step 1: Check server health
curl https://vvuq.dirkenglund.org/health
# Step 2: Create a contract
CONTRACT_RESPONSE=$(curl -X POST https://vvuq.dirkenglund.org/api/v1/contracts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Commutativity of Addition",
"description": "Prove that addition is commutative",
"issuer_agent_id": "alice",
"claims": [{
"claim_id": 1,
"theorem": "ā (a b : ā), a + b = b + a",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 100.0,
"payment_type": "all-or-nothing"
}]
}')
CONTRACT_ID=$(echo "$CONTRACT_RESPONSE" | jq -r '.contract_id')
echo "Created contract: $CONTRACT_ID"
# Step 3: Submit a proof
PROOF_RESPONSE=$(curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"contract_id\": \"$CONTRACT_ID\",
\"claim_id\": 1,
\"proof_code\": \"import Mathlib.Data.Nat.Basic\\n\\ntheorem nat_add_comm : ā (a b : ā), a + b = b + a := fun a b => Nat.add_comm a b\",
\"prover_agent_id\": \"bob\"
}")
VERIFICATION_ID=$(echo "$PROOF_RESPONSE" | jq -r '.verification_id')
echo "Verification started: $VERIFICATION_ID"
# Step 4: Poll for verification status
while true; do
STATUS=$(curl -s -H "Authorization: Bearer YOUR_API_KEY" \
"https://vvuq.dirkenglund.org/api/v1/verifications/$VERIFICATION_ID/status")
PROGRESS=$(echo "$STATUS" | jq -r '.progress')
STATUS_VAL=$(echo "$STATUS" | jq -r '.status')
echo "Progress: $PROGRESS% - Status: $STATUS_VAL"
if [ "$STATUS_VAL" = "completed" ]; then
VERDICT=$(echo "$STATUS" | jq -r '.result.verdict')
echo "ā
Verification complete: $VERDICT"
break
fi
sleep 1
done
# Step 5: Get verification history
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://vvuq.dirkenglund.org/api/v1/contracts/$CONTRACT_ID/history" | jq
```
**Expected Result:**
```json
{
"verdict": "ACCEPTED",
"matches_claim": true,
"verification_time_ms": 1250
}
```
---
## Contract Creation Examples
### Example 1: Simple Addition Theorem
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/contracts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Addition Identity",
"description": "Prove n + 0 = n for natural numbers",
"issuer_agent_id": "alice",
"claims": [{
"claim_id": 1,
"theorem": "ā (n : ā), n + 0 = n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 50.0,
"payment_type": "all-or-nothing"
}]
}'
```
**Response:**
```json
{
"success": true,
"contract_id": "contract_abc123",
"message": "Contract 'Addition Identity' created successfully"
}
```
---
### Example 2: Multi-Claim Contract
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/contracts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Basic Arithmetic Properties",
"description": "Multiple claims about natural number arithmetic",
"issuer_agent_id": "mathematics_dept",
"claims": [
{
"claim_id": 1,
"theorem": "ā (n : ā), n + 0 = n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 50.0,
"payment_type": "all-or-nothing"
},
{
"claim_id": 2,
"theorem": "ā (n : ā), 0 + n = n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 50.0,
"payment_type": "all-or-nothing"
},
{
"claim_id": 3,
"theorem": "ā (a b : ā), a + b = b + a",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 100.0,
"payment_type": "all-or-nothing"
}
]
}'
```
**Use Case:** Multiple related claims in one contract. Each claim can be proven independently.
---
### Example 3: Contract with Mathlib Version Pinning
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/contracts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Ring Theory Proof (Mathlib v4.15.0)",
"description": "Prove using specific Mathlib version for reproducibility",
"issuer_agent_id": "research_group",
"claims": [{
"claim_id": 1,
"theorem": "ā (R : Type) [CommRing R] (a b c : R), a * (b + c) = a * b + a * c",
"allowed_dependencies": [
"Mathlib.Algebra.Ring.Basic",
"Mathlib.Tactic.Ring"
],
"payment_amount": 200.0,
"payment_type": "all-or-nothing",
"mathlib_version": "v4.15.0",
"assumption_contexts": []
}]
}'
```
**Use Case:** Pin to specific Mathlib version for reproducible builds.
---
## Proof Submission Examples
### Example 1: Successful Proof
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "contract_abc123",
"claim_id": 1,
"proof_code": "import Mathlib.Data.Nat.Basic\n\ntheorem nat_add_zero : ā (n : ā), n + 0 = n := fun n => Nat.add_zero n",
"prover_agent_id": "bob"
}'
```
**Response (202 Accepted - Async):**
```json
{
"verification_id": "verify_xyz789",
"status_url": "/api/v1/verifications/verify_xyz789/status",
"estimated_completion_seconds": 15,
"message": "Verification in progress"
}
```
**Then poll status:**
```bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://vvuq.dirkenglund.org/api/v1/verifications/verify_xyz789/status"
```
**Final Result:**
```json
{
"status": "completed",
"result": {
"verdict": "ACCEPTED",
"matches_claim": true,
"verification_time_ms": 1250,
"errors": []
}
}
```
---
### Example 2: Proof with Tactics
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "contract_ring123",
"claim_id": 1,
"proof_code": "import Mathlib.Algebra.Ring.Basic\nimport Mathlib.Tactic.Ring\n\nvariable (R : Type) [CommRing R]\n\ntheorem distributivity (a b c : R) : a * (b + c) = a * b + a * c := by\n ring",
"prover_agent_id": "formal_methods_team"
}'
```
**Use Case:** Using Lean tactics (`ring`) for automated proof search.
---
### Example 3: Rejected Proof (Dependency Violation)
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "contract_abc123",
"claim_id": 1,
"proof_code": "import Mathlib.Data.Real.Basic\n\ntheorem bad_proof : ā (n : ā), n + 0 = n := sorry",
"prover_agent_id": "cheater"
}'
```
**Result:**
```json
{
"status": "completed",
"result": {
"verdict": "REJECTED",
"errors": [
"Unauthorized import: Mathlib.Data.Real.Basic",
"Contains sorry keyword"
],
"unauthorized_dependencies": ["Mathlib.Data.Real.Basic"],
"sorry_count": 1
}
}
```
**Use Case:** System correctly rejects proofs with unauthorized dependencies or `sorry`.
---
## Advanced Workflows
### Workflow 1: Batch Contract Creation
```python
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://vvuq.dirkenglund.org"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Create 10 related contracts
contracts = []
for i in range(1, 11):
contract_data = {
"title": f"Theorem {i}: Addition Properties",
"description": f"Property {i} of natural number addition",
"issuer_agent_id": "batch_issuer",
"claims": [{
"claim_id": 1,
"theorem": f"ā (n : ā), n + {i} = {i} + n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 10.0 * i,
"payment_type": "all-or-nothing"
}]
}
response = requests.post(
f"{BASE_URL}/api/v1/contracts",
headers=headers,
json=contract_data
)
if response.status_code == 201:
contract_id = response.json()["contract_id"]
contracts.append(contract_id)
print(f"ā
Created contract {i}: {contract_id}")
else:
print(f"ā Failed to create contract {i}: {response.text}")
print(f"\nā
Created {len(contracts)} contracts total")
```
**Expected Output:**
```
ā
Created contract 1: contract_abc001
ā
Created contract 2: contract_abc002
...
ā
Created 10 contracts total
```
---
### Workflow 2: Concurrent Proof Submission
```python
import requests
import asyncio
import aiohttp
async def submit_proof_async(session, contract_id, claim_id, proof_code, prover_id):
"""Submit proof asynchronously."""
url = "https://vvuq.dirkenglund.org/api/v1/proofs/submit"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"contract_id": contract_id,
"claim_id": claim_id,
"proof_code": proof_code,
"prover_agent_id": prover_id
}
async with session.post(url, headers=headers, json=data) as response:
return await response.json()
async def main():
# Submit 5 proofs concurrently
async with aiohttp.ClientSession() as session:
tasks = []
for i in range(1, 6):
proof_code = f"""import Mathlib.Data.Nat.Basic
theorem test_{i} : ā (n : ā), n + 0 = n :=
fun n => Nat.add_zero n
"""
task = submit_proof_async(
session,
f"contract_{i}",
1,
proof_code,
f"prover_{i}"
)
tasks.append(task)
results = await asyncio.gather(*tasks)
for i, result in enumerate(results, 1):
print(f"Proof {i}: {result.get('verification_id', 'Error')}")
asyncio.run(main())
```
**Use Case:** Submit multiple proofs in parallel for faster throughput.
---
### Workflow 3: Verification Status Polling with Retry
```python
import requests
import time
def poll_verification(verification_id, api_key, max_attempts=60, interval=1):
"""
Poll verification status with timeout and retry logic.
Args:
verification_id: Verification job identifier
api_key: API authentication key
max_attempts: Maximum polling attempts (default: 60)
interval: Seconds between polls (default: 1)
Returns:
Final verification result
"""
url = f"https://vvuq.dirkenglund.org/api/v1/verifications/{verification_id}/status"
headers = {"Authorization": f"Bearer {api_key}"}
for attempt in range(max_attempts):
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
status_val = data.get("status")
progress = data.get("progress", 0)
print(f"Attempt {attempt + 1}: Progress {progress}% - {status_val}")
if status_val == "completed":
result = data.get("result", {})
verdict = result.get("verdict")
if verdict == "ACCEPTED":
print(f"ā
Proof ACCEPTED in {result.get('verification_time_ms')}ms")
return {"success": True, "data": data}
else:
print(f"ā Proof REJECTED: {result.get('errors')}")
return {"success": False, "data": data}
elif status_val == "failed":
error = data.get("error_message")
print(f"ā Verification failed: {error}")
return {"success": False, "error": error}
time.sleep(interval)
except requests.exceptions.RequestException as e:
print(f"ā ļø Network error on attempt {attempt + 1}: {e}")
time.sleep(interval * 2) # Backoff on errors
print(f"ā±ļø Timeout after {max_attempts} attempts")
return {"success": False, "error": "Timeout"}
# Usage
result = poll_verification(
"verify_xyz789",
"YOUR_API_KEY",
max_attempts=30,
interval=1
)
if result["success"]:
print("š Proof verified successfully!")
else:
print(f"š Verification failed: {result.get('error')}")
```
**Use Case:** Robust polling with timeout and error handling.
---
## Contract Creation Examples
### Example 4: Physics/Engineering Theorem
```json
{
"title": "Hooke's Law Verification",
"description": "Verify linear relationship between force and displacement",
"issuer_agent_id": "physics_lab",
"claims": [{
"claim_id": 1,
"theorem": "ā (k x : ā), k > 0 ā F = k * x ā linear_relationship F x",
"allowed_dependencies": [
"Mathlib.Data.Real.Basic",
"Mathlib.Algebra.Field.Basic"
],
"payment_amount": 500.0,
"payment_type": "all-or-nothing",
"mathlib_version": "v4.19.1"
}]
}
```
---
### Example 5: Algorithm Correctness
```json
{
"title": "Sorting Algorithm Correctness",
"description": "Prove sorting algorithm produces sorted output",
"issuer_agent_id": "cs_department",
"claims": [{
"claim_id": 1,
"theorem": "ā (list : List ā), sorted (quicksort list) ā§ permutation list (quicksort list)",
"allowed_dependencies": [
"Mathlib.Data.List.Basic",
"Mathlib.Data.List.Sort"
],
"payment_amount": 1000.0,
"payment_type": "graded"
}]
}
```
---
### Example 6: Multiple Claims with Different Payment Types
```json
{
"title": "Mixed Payment Contract",
"description": "Different payment types for different complexity levels",
"issuer_agent_id": "research_fund",
"claims": [
{
"claim_id": 1,
"theorem": "ā (n : ā), n ⤠n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 10.0,
"payment_type": "all-or-nothing"
},
{
"claim_id": 2,
"theorem": "ā (a b c : ā), a ⤠b ā b ⤠c ā a ⤠c",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 100.0,
"payment_type": "partial"
},
{
"claim_id": 3,
"theorem": "ā (n : ā), prime n ā n > 1",
"allowed_dependencies": [
"Mathlib.Data.Nat.Prime",
"Mathlib.Data.Nat.Basic"
],
"payment_amount": 500.0,
"payment_type": "graded"
}
]
}
```
**Payment Types:**
- `all-or-nothing`: Full payment for complete proof
- `partial`: Proportional payment for partial progress
- `graded`: Payment based on quality score
---
## Proof Submission Examples
### Example 7: Proof with Explicit Type Annotations
```lean
import Mathlib.Data.Nat.Basic
theorem add_comm_explicit : ā (a b : ā), a + b = b + a := by
intro a b
rw [Nat.add_comm]
```
**Submission:**
```bash
PROOF_CODE='import Mathlib.Data.Nat.Basic
theorem add_comm_explicit : ā (a b : ā), a + b = b + a := by
intro a b
rw [Nat.add_comm]'
curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"contract_id\": \"contract_abc123\",
\"claim_id\": 1,
\"proof_code\": $(echo "$PROOF_CODE" | jq -Rs .),
\"prover_agent_id\": \"tactic_prover\"
}"
```
---
### Example 8: Proof Using ring Tactic
```lean
import Mathlib.Algebra.Ring.Basic
import Mathlib.Tactic.Ring
variable (R : Type) [CommRing R]
theorem ring_distributivity (a b c : R) : a * (b + c) = a * b + a * c := by
ring
```
**Use Case:** Automated proof using powerful `ring` tactic.
---
### Example 9: Rejected Proof - Wrong Theorem
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "contract_abc123",
"claim_id": 1,
"proof_code": "import Mathlib.Data.Nat.Basic\n\n-- Proving WRONG theorem!\ntheorem wrong_theorem : ā (n : ā), n + 1 = n := sorry",
"prover_agent_id": "mistake_maker"
}'
```
**Result:**
```json
{
"result": {
"verdict": "REJECTED",
"matches_claim": false,
"errors": [
"Mismatch! Proven: 'ā (n : ā), n + 1 = n' vs Expected: 'ā (n : ā), n + 0 = n'",
"Contains sorry keyword"
],
"sorry_count": 1
}
}
```
**Use Case:** System correctly rejects proofs that don't match the claim.
---
## Python Client Examples
### Example 10: Complete Python Client
```python
import requests
import time
from typing import Dict, List, Optional, Any
class VVUQClient:
"""
Python client for VVUQ-MCP API.
Handles authentication, retry logic, and polling automatically.
"""
def __init__(self, api_key: str, base_url: str = "https://vvuq.dirkenglund.org"):
self.api_key = api_key
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
})
def health_check(self) -> Dict[str, Any]:
"""Check server health."""
response = self.session.get(f"{self.base_url}/health")
response.raise_for_status()
return response.json()
def create_contract(
self,
title: str,
description: str,
issuer_agent_id: str,
claims: List[Dict[str, Any]]
) -> str:
"""
Create a new verification contract.
Args:
title: Contract title
description: Contract description
issuer_agent_id: Issuer identifier
claims: List of claim dictionaries
Returns:
contract_id of created contract
"""
data = {
"title": title,
"description": description,
"issuer_agent_id": issuer_agent_id,
"claims": claims
}
response = self.session.post(
f"{self.base_url}/api/v1/contracts",
json=data
)
response.raise_for_status()
return response.json()["contract_id"]
def get_contract(self, contract_id: str) -> Dict[str, Any]:
"""Get contract details."""
response = self.session.get(
f"{self.base_url}/api/v1/contracts/{contract_id}"
)
response.raise_for_status()
return response.json()
def submit_proof(
self,
contract_id: str,
claim_id: int,
proof_code: str,
prover_agent_id: str
) -> str:
"""
Submit proof for verification (async).
Args:
contract_id: Contract identifier
claim_id: Claim ID (not array index!)
proof_code: Lean4 proof code
prover_agent_id: Prover identifier
Returns:
verification_id for status polling
"""
data = {
"contract_id": contract_id,
"claim_id": claim_id, # Use claim_id, not proof_claim_index!
"proof_code": proof_code,
"prover_agent_id": prover_agent_id
}
response = self.session.post(
f"{self.base_url}/api/v1/proofs/submit",
json=data
)
response.raise_for_status()
return response.json()["verification_id"]
def get_verification_status(self, verification_id: str) -> Dict[str, Any]:
"""Get verification status."""
response = self.session.get(
f"{self.base_url}/api/v1/verifications/{verification_id}/status"
)
response.raise_for_status()
return response.json()
def wait_for_verification(
self,
verification_id: str,
max_wait: int = 60,
interval: float = 1.0,
callback: Optional[callable] = None
) -> Dict[str, Any]:
"""
Poll verification until complete.
Args:
verification_id: Verification identifier
max_wait: Maximum seconds to wait
interval: Seconds between polls
callback: Optional callback(status_data) for progress updates
Returns:
Final verification result
"""
start_time = time.time()
while time.time() - start_time < max_wait:
status_data = self.get_verification_status(verification_id)
if callback:
callback(status_data)
if status_data["status"] == "completed":
return status_data
elif status_data["status"] == "failed":
raise Exception(f"Verification failed: {status_data.get('error_message')}")
time.sleep(interval)
raise TimeoutError(f"Verification did not complete within {max_wait}s")
def submit_and_wait(
self,
contract_id: str,
claim_id: int,
proof_code: str,
prover_agent_id: str,
verbose: bool = True
) -> Dict[str, Any]:
"""
Submit proof and wait for result (convenience method).
Returns:
Complete verification result
"""
# Submit proof
verification_id = self.submit_proof(
contract_id, claim_id, proof_code, prover_agent_id
)
if verbose:
print(f"š Proof submitted: {verification_id}")
# Wait for completion with progress callback
def progress_callback(status):
if verbose:
progress = status.get("progress", 0)
current_step = status.get("current_step", "Unknown")
print(f"ā³ Progress: {progress}% - {current_step}")
result = self.wait_for_verification(
verification_id,
callback=progress_callback if verbose else None
)
verdict = result["result"]["verdict"]
if verdict == "ACCEPTED":
if verbose:
print(f"ā
Proof ACCEPTED!")
else:
if verbose:
errors = result["result"].get("errors", [])
print(f"ā Proof REJECTED: {errors}")
return result
def submit_feedback(
self,
title: str,
description: str,
feedback_type: str = "general",
severity: str = "medium",
**kwargs
) -> str:
"""
Submit feedback about the API.
Args:
title: Feedback title
description: Detailed description
feedback_type: bug|feature_request|improvement|etc.
severity: critical|high|medium|low
Returns:
feedback_id
"""
data = {
"title": title,
"description": description,
"feedback_type": feedback_type,
"severity": severity,
"submitter_type": "agent",
**kwargs
}
response = self.session.post(
f"{self.base_url}/api/v1/feedback/submit",
json=data
)
response.raise_for_status()
return response.json()["feedback_id"]
def list_rulesets(self) -> List[Dict[str, Any]]:
"""Get all available verification rulesets."""
response = self.session.get(f"{self.base_url}/api/v1/rulesets")
response.raise_for_status()
return response.json()["rulesets"]
def get_ruleset(self, ruleset_id: str) -> Dict[str, Any]:
"""Get specific ruleset details."""
response = self.session.get(
f"{self.base_url}/api/v1/rulesets/{ruleset_id}"
)
response.raise_for_status()
return response.json()
# =============================================================================
# USAGE EXAMPLES
# =============================================================================
# Initialize client
client = VVUQClient("vvuq_YOUR_KEY_HERE")
# Example 1: Simple workflow
contract_id = client.create_contract(
title="Test Theorem",
description="Testing the client",
issuer_agent_id="alice",
claims=[{
"claim_id": 1,
"theorem": "ā (n : ā), n + 0 = n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 100.0,
"payment_type": "all-or-nothing"
}]
)
proof_code = """import Mathlib.Data.Nat.Basic
theorem nat_add_zero : ā (n : ā), n + 0 = n :=
fun n => Nat.add_zero n
"""
result = client.submit_and_wait(
contract_id=contract_id,
claim_id=1,
proof_code=proof_code,
prover_agent_id="bob",
verbose=True
)
if result["result"]["verdict"] == "ACCEPTED":
print("š Success!")
# Example 2: List available security rulesets
rulesets = client.list_rulesets()
for ruleset in rulesets:
print(f"⢠{ruleset['ruleset_id']}: {ruleset['name']}")
```
---
## Error Handling
### Example 11: Comprehensive Error Handling
```python
import requests
from requests.exceptions import HTTPError, Timeout, ConnectionError
class VVUQError(Exception):
"""Base exception for VVUQ client errors."""
pass
class AuthenticationError(VVUQError):
"""Invalid API key."""
pass
class ContractNotFoundError(VVUQError):
"""Contract doesn't exist."""
pass
class VerificationError(VVUQError):
"""Verification failed."""
pass
def safe_api_call(url, api_key, method="GET", data=None):
"""
Make API call with comprehensive error handling.
Returns:
Parsed JSON response
Raises:
Specific VVUQ exceptions based on error type
"""
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
try:
if method == "GET":
response = requests.get(url, headers=headers, timeout=30)
elif method == "POST":
response = requests.post(url, headers=headers, json=data, timeout=30)
else:
raise ValueError(f"Unsupported method: {method}")
response.raise_for_status()
return response.json()
except HTTPError as e:
status_code = e.response.status_code
if status_code == 401:
raise AuthenticationError("Missing API key")
elif status_code == 403:
raise AuthenticationError("Invalid API key")
elif status_code == 404:
# Parse error details
try:
error_data = e.response.json()
error_code = error_data.get("detail", {}).get("error_code", "")
if "CONTRACT_NOT_FOUND" in error_code:
raise ContractNotFoundError(f"Contract not found: {url}")
elif "CLAIM_NOT_FOUND" in error_code:
raise ContractNotFoundError(f"Claim not found in contract")
else:
raise VVUQError(f"Not found: {error_data}")
except:
raise VVUQError(f"Resource not found: {url}")
elif status_code == 422:
# Validation error
error_data = e.response.json()
details = error_data.get("detail", [])
raise ValueError(f"Validation error: {details}")
elif status_code >= 500:
# Server error - include error_id for support
try:
error_data = e.response.json()
error_id = error_data.get("detail", {}).get("error_id", "unknown")
raise VVUQError(f"Server error (ID: {error_id}). Contact support.")
except:
raise VVUQError(f"Server error: {e}")
else:
raise VVUQError(f"HTTP {status_code}: {e}")
except Timeout:
raise VVUQError("Request timeout - server may be overloaded")
except ConnectionError:
raise VVUQError("Connection error - check network or server status")
# Usage
try:
result = safe_api_call(
"https://vvuq.dirkenglund.org/api/v1/contracts/invalid_id",
"YOUR_API_KEY"
)
except AuthenticationError as e:
print(f"Auth error: {e}")
except ContractNotFoundError as e:
print(f"Contract error: {e}")
except VVUQError as e:
print(f"API error: {e}")
```
---
## Security & Rulesets
### Example 12: Get Security Ruleset
```bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://vvuq.dirkenglund.org/api/v1/rulesets/security:v1.0.0" | jq
```
**Response:**
```json
{
"ruleset_id": "security:v1.0.0",
"name": "OWASP Top 10 Security Rules",
"description": "Comprehensive security ruleset based on OWASP Top 10 vulnerabilities with formal verification",
"version": "1.0.0",
"rules": [
{
"rule_id": "A01:sql-injection",
"name": "SQL Injection Prevention",
"severity": "critical",
"category": "security",
"cwe": "CWE-89",
"owasp": "A01:2021-Injection",
"theorem_template": "theorem no_sql_injection_{id} (query : String) (user_input : String) : parameterized_query query ā sanitized (query ++ user_input)"
}
]
}
```
---
### Example 13: Create Custom Ruleset
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/rulesets \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ruleset_id": "physics:v1.0.0",
"name": "Physics Verification Rules",
"description": "Rules for verifying physics calculations",
"version": "1.0.0",
"category": "physics",
"rules": [{
"rule_id": "dimensional-analysis",
"name": "Dimensional Analysis Check",
"severity": "high",
"category": "physics",
"description": "Verify dimensional consistency in equations",
"theorem_template": "theorem dimensional_consistency_{id} (eq : Equation) : dimensions_match eq"
}]
}'
```
---
## Feedback & Support
### Example 14: Submit Bug Report
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/feedback/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Proof verification timeout on large proofs",
"description": "Proofs larger than 50KB timeout even with valid syntax",
"feedback_type": "bug",
"severity": "high",
"submitter_type": "agent",
"tool_name": "proofs/submit",
"reproduction_steps": "1. Create contract\n2. Submit 100KB proof\n3. Verification times out after 120s"
}'
```
**Response:**
```json
{
"success": true,
"feedback_id": "feedback_abc123",
"message": "Feedback submitted successfully (GitHub issue pending)",
"github_issue_created": true
}
```
**Note:** GitHub issue creation happens in background (<200ms response time).
---
### Example 15: Submit Feature Request
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/feedback/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Add support for Coq proofs",
"description": "Would like to verify Coq proofs in addition to Lean4",
"feedback_type": "feature_request",
"severity": "medium",
"submitter_type": "person"
}'
```
---
## Real-World Use Cases
### Use Case 1: Academic Course (Proof Assignments)
```python
# Professor creates contract for student homework
client = VVUQClient("YOUR_API_KEY")
contract_id = client.create_contract(
title="CS 499 Homework 3: Sorting Algorithms",
description="Prove correctness of merge sort algorithm",
issuer_agent_id="prof_smith",
claims=[{
"claim_id": 1,
"theorem": "ā (list : List ā), sorted (mergeSort list) ā§ permutation list (mergeSort list)",
"allowed_dependencies": [
"Mathlib.Data.List.Basic",
"Mathlib.Data.List.Sort"
],
"payment_amount": 10.0, # Course credit points
"payment_type": "graded"
}]
)
print(f"Homework contract: {contract_id}")
# Students submit proofs
proof = """import Mathlib.Data.List.Basic
import Mathlib.Data.List.Sort
-- Student solution here
theorem mergeSort_correct : ā (list : List ā),
sorted (mergeSort list) ā§ permutation list (mergeSort list) := by
sorry -- Student fills this in
"""
result = client.submit_and_wait(
contract_id=contract_id,
claim_id=1,
proof_code=proof,
prover_agent_id="student_john_doe",
verbose=True
)
# Automated grading based on verdict
if result["result"]["verdict"] == "ACCEPTED":
grade = 100
elif result["result"]["sorry_count"] == 0:
grade = 70 # Partial credit
else:
grade = 0
print(f"Grade: {grade}/100")
```
---
### Use Case 2: Open Bounty System
```python
# Organization posts bounty for hard theorem
contract_id = client.create_contract(
title="Bounty: Goldbach Conjecture Special Case",
description="$10,000 bounty for formal verification",
issuer_agent_id": "math_foundation",
claims=[{
"claim_id": 1,
"theorem": "ā (n : ā), n > 2 ā§ Even n ā ā (p q : ā), Prime p ā§ Prime q ā§ n = p + q",
"allowed_dependencies": [
"Mathlib.Data.Nat.Prime",
"Mathlib.Data.Nat.Parity"
],
"payment_amount": 10000.0,
"payment_type": "all-or-nothing",
"mathlib_version": "v4.19.1" # Pin for reproducibility
}]
)
print(f"Bounty posted: https://vvuq.dirkenglund.org/contracts/{contract_id}")
# Anyone can submit proof
# First valid proof wins the bounty
```
---
### Use Case 3: Code Review with Formal Verification
```python
# Use OWASP security ruleset to verify code
rulesets = client.list_rulesets()
security_ruleset = next(r for r in rulesets if "security" in r["ruleset_id"].lower())
print(f"Using ruleset: {security_ruleset['name']}")
# Create contract for security proof
contract_id = client.create_contract(
title="Security Verification: User Input Sanitization",
description="Prove user input is properly sanitized",
issuer_agent_id="security_team",
claims=[{
"claim_id": 1,
"theorem": "ā (input : String), sanitized (escape_html input) ā no_xss_risk (render input)",
"allowed_dependencies": [],
"payment_amount": 500.0,
"payment_type": "all-or-nothing"
}]
)
# Automated proof generator attempts verification
# If successful, code review passes
```
---
## Advanced Examples
### Example 16: Retry Logic with Exponential Backoff
```python
import time
import random
def submit_proof_with_retry(
client: VVUQClient,
contract_id: str,
claim_id: int,
proof_code: str,
prover_agent_id: str,
max_retries: int = 3
) -> Optional[str]:
"""
Submit proof with exponential backoff on rate limit errors.
Returns:
verification_id on success, None on failure
"""
for attempt in range(max_retries):
try:
verification_id = client.submit_proof(
contract_id, claim_id, proof_code, prover_agent_id
)
return verification_id
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429: # Too Many Requests
# Exponential backoff
wait_time = (2 ** attempt) + random.uniform(0, 1)
print(f"ā³ Rate limited. Retrying in {wait_time:.1f}s...")
time.sleep(wait_time)
else:
raise
print(f"ā Failed after {max_retries} attempts")
return None
# Usage
verification_id = submit_proof_with_retry(
client,
"contract_abc123",
1,
proof_code,
"my_agent"
)
```
---
### Example 17: Proof Validation Before Submission
```python
def validate_proof_locally(proof_code: str) -> Dict[str, Any]:
"""
Pre-validate proof before submitting to API.
Checks:
- No 'sorry' keywords
- Has proper theorem statement
- Imports are present
- Reasonable size
Returns:
Dict with validation results
"""
errors = []
# Check 1: No sorry
if "sorry" in proof_code.lower():
errors.append("Proof contains 'sorry' keyword - incomplete")
# Check 2: Has theorem/lemma/example
if not any(keyword in proof_code for keyword in ["theorem ", "lemma ", "example "]):
errors.append("No theorem/lemma/example found")
# Check 3: Has imports
if "import " not in proof_code:
errors.append("No import statements - may fail compilation")
# Check 4: Size limit (100KB)
if len(proof_code.encode('utf-8')) > 100_000:
errors.append(f"Proof too large: {len(proof_code)} bytes (max: 100KB)")
# Check 5: Has type annotation (ā or ā)
if not any(symbol in proof_code for symbol in ["ā", "ā", ":", ":="]):
errors.append("Missing type annotations")
return {
"valid": len(errors) == 0,
"errors": errors,
"size_bytes": len(proof_code.encode('utf-8'))
}
# Usage
proof = """import Mathlib.Data.Nat.Basic
theorem test : ā (n : ā), n + 0 = n := by
intro n
rw [Nat.add_zero]
"""
validation = validate_proof_locally(proof)
if validation["valid"]:
print("ā
Proof valid locally, submitting...")
verification_id = client.submit_proof(...)
else:
print(f"ā Proof validation failed:")
for error in validation["errors"]:
print(f" ⢠{error}")
```
---
### Example 18: Batch Verification with Progress Tracking
```python
import asyncio
import aiohttp
from dataclasses import dataclass
from typing import List
@dataclass
class ProofJob:
contract_id: str
claim_id: int
proof_code: str
prover_agent_id: str
@dataclass
class VerificationResult:
job_index: int
verification_id: str
verdict: Optional[str] = None
errors: List[str] = None
async def batch_verify_proofs(
proofs: List[ProofJob],
api_key: str,
callback = None
) -> List[VerificationResult]:
"""
Submit multiple proofs concurrently and track results.
Args:
proofs: List of ProofJob objects
api_key: API authentication key
callback: Optional callback(job_index, status) for progress
Returns:
List of VerificationResult objects
"""
base_url = "https://vvuq.dirkenglund.org"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
results = []
async with aiohttp.ClientSession() as session:
# Phase 1: Submit all proofs concurrently
submit_tasks = []
for i, proof in enumerate(proofs):
data = {
"contract_id": proof.contract_id,
"claim_id": proof.claim_id,
"proof_code": proof.proof_code,
"prover_agent_id": proof.prover_agent_id
}
task = session.post(
f"{base_url}/api/v1/proofs/submit",
headers=headers,
json=data
)
submit_tasks.append((i, task))
# Gather submission results
for i, task in submit_tasks:
async with task as response:
if response.status == 202:
data = await response.json()
verification_id = data["verification_id"]
results.append(VerificationResult(
job_index=i,
verification_id=verification_id
))
print(f"ā
Submitted proof {i + 1}/{len(proofs)}: {verification_id}")
# Phase 2: Poll all verifications concurrently
async def poll_verification(result: VerificationResult):
while True:
async with session.get(
f"{base_url}/api/v1/verifications/{result.verification_id}/status",
headers=headers
) as response:
status_data = await response.json()
if callback:
callback(result.job_index, status_data)
if status_data["status"] == "completed":
result.verdict = status_data["result"]["verdict"]
result.errors = status_data["result"].get("errors", [])
break
await asyncio.sleep(1)
# Wait for all verifications
await asyncio.gather(*[poll_verification(r) for r in results])
return results
# Usage
async def main():
proofs = [
ProofJob(
contract_id="contract_1",
claim_id=1,
proof_code="import Mathlib.Data.Nat.Basic\n\ntheorem test1 : ā (n : ā), n + 0 = n := fun n => Nat.add_zero n",
prover_agent_id="prover_1"
),
ProofJob(
contract_id="contract_2",
claim_id=1,
proof_code="import Mathlib.Data.Nat.Basic\n\ntheorem test2 : ā (n : ā), 0 + n = n := fun n => Nat.zero_add n",
prover_agent_id="prover_2"
),
# ... more proofs
]
def progress_callback(job_index, status):
progress = status.get("progress", 0)
print(f"Proof {job_index + 1}: {progress}%")
results = await batch_verify_proofs(
proofs,
"YOUR_API_KEY",
callback=progress_callback
)
# Summary
accepted = sum(1 for r in results if r.verdict == "ACCEPTED")
rejected = sum(1 for r in results if r.verdict == "REJECTED")
print(f"\nš Results: {accepted} ACCEPTED, {rejected} REJECTED")
for r in results:
status_icon = "ā
" if r.verdict == "ACCEPTED" else "ā"
print(f"{status_icon} Proof {r.job_index + 1}: {r.verdict}")
asyncio.run(main())
```
**Use Case:** Submit 100+ proofs in parallel, track progress, get summary.
---
## Testing & Validation
### Example 19: Integration Test Suite
```python
import pytest
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://vvuq.dirkenglund.org"
def test_health_check():
"""Verify server is healthy."""
response = requests.get(f"{BASE_URL}/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
assert data["storage_connected"] == True
assert data["verifier_ready"] == True
def test_create_and_verify_simple_proof():
"""End-to-end test: Create contract, submit proof, verify result."""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Create contract
contract_data = {
"title": "Integration Test",
"description": "Testing E2E workflow",
"issuer_agent_id": "test_suite",
"claims": [{
"claim_id": 1,
"theorem": "ā (n : ā), n + 0 = n",
"allowed_dependencies": ["Mathlib.Data.Nat.Basic"],
"payment_amount": 1.0,
"payment_type": "all-or-nothing"
}]
}
response = requests.post(
f"{BASE_URL}/api/v1/contracts",
headers=headers,
json=contract_data
)
assert response.status_code == 201
contract_id = response.json()["contract_id"]
assert contract_id.startswith("contract_")
# Submit valid proof
proof_data = {
"contract_id": contract_id,
"claim_id": 1,
"proof_code": "import Mathlib.Data.Nat.Basic\n\ntheorem nat_add_zero : ā (n : ā), n + 0 = n := fun n => Nat.add_zero n",
"prover_agent_id": "test_prover"
}
response = requests.post(
f"{BASE_URL}/api/v1/proofs/submit",
headers=headers,
json=proof_data
)
assert response.status_code == 202
verification_id = response.json()["verification_id"]
# Poll until complete (max 30 seconds)
import time
max_wait = 30
start = time.time()
while time.time() - start < max_wait:
response = requests.get(
f"{BASE_URL}/api/v1/verifications/{verification_id}/status",
headers=headers
)
assert response.status_code == 200
status_data = response.json()
if status_data["status"] == "completed":
verdict = status_data["result"]["verdict"]
assert verdict == "ACCEPTED"
return
time.sleep(1)
pytest.fail("Verification did not complete in time")
# Run tests
if __name__ == "__main__":
pytest.main([__file__, "-v"])
```
---
## Common Patterns & Best Practices
### Pattern 1: Idempotent Proof Submission
```python
import hashlib
def submit_proof_idempotent(
client: VVUQClient,
contract_id: str,
claim_id: int,
proof_code: str,
prover_agent_id: str
) -> str:
"""
Submit proof with idempotency key to prevent duplicates.
Uses proof code hash as idempotency key.
"""
# Generate idempotency key from proof content
proof_hash = hashlib.sha256(
f"{contract_id}:{claim_id}:{proof_code}".encode()
).hexdigest()[:16]
idempotency_key = f"proof_{proof_hash}"
# Submit with custom header
headers = {
"Authorization": f"Bearer {client.api_key}",
"Content-Type": "application/json",
"X-Idempotency-Key": idempotency_key
}
data = {
"contract_id": contract_id,
"claim_id": claim_id,
"proof_code": proof_code,
"prover_agent_id": prover_agent_id
}
response = client.session.post(
f"{client.base_url}/api/v1/proofs/submit",
headers=headers,
json=data
)
response.raise_for_status()
return response.json()["verification_id"]
```
**Use Case:** Prevent duplicate proof submissions on network retry.
---
### Pattern 2: Graceful Degradation
```python
def get_contract_with_fallback(
client: VVUQClient,
contract_id: str,
fallback_data: Optional[Dict] = None
) -> Dict[str, Any]:
"""
Get contract with graceful degradation.
Returns cached/fallback data if API unavailable.
"""
try:
return client.get_contract(contract_id)
except requests.exceptions.Timeout:
print("ā ļø API timeout - using cached data")
return fallback_data or {"error": "timeout"}
except requests.exceptions.ConnectionError:
print("ā ļø Connection error - using cached data")
return fallback_data or {"error": "connection_error"}
except AuthenticationError:
print("ā Authentication failed - check API key")
raise
except Exception as e:
print(f"ā ļø Unexpected error: {e}")
return fallback_data or {"error": str(e)}
```
---
## Quick Reference
### curl Cheat Sheet
```bash
# Health (no auth)
curl https://vvuq.dirkenglund.org/health
# List contracts
curl -H "Authorization: Bearer YOUR_KEY" \
"https://vvuq.dirkenglund.org/api/v1/contracts?status=OPEN"
# Create contract
curl -X POST https://vvuq.dirkenglund.org/api/v1/contracts \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d @contract.json
# Submit proof
curl -X POST https://vvuq.dirkenglund.org/api/v1/proofs/submit \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d @proof.json
# Check status
curl -H "Authorization: Bearer YOUR_KEY" \
"https://vvuq.dirkenglund.org/api/v1/verifications/VERIFICATION_ID/status"
# List rulesets
curl -H "Authorization: Bearer YOUR_KEY" \
"https://vvuq.dirkenglund.org/api/v1/rulesets"
# Submit feedback
curl -X POST https://vvuq.dirkenglund.org/api/v1/feedback/submit \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d @feedback.json
```
---
## Important Notes
### ā ļø Breaking Change Alert (2026-01-04)
**Old API (DEPRECATED):**
```json
{
"proof_claim_index": 0 // Array index - NO LONGER WORKS
}
```
**New API (REQUIRED):**
```json
{
"claim_id": 1 // Actual claim ID field
}
```
**Migration:** Update all `proof_claim_index` to `claim_id` in your code.
### Rate Limiting
**Limits:**
- 10 requests/second per agent (sustained)
- 20 request burst allowed
- Fair allocation across agents
**Handling Rate Limits:**
```python
try:
result = client.submit_proof(...)
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
retry_after = e.response.headers.get("Retry-After", 2)
time.sleep(int(retry_after))
result = client.submit_proof(...) # Retry
```
### Security Features
**All requests:**
- Constant-time API key comparison (timing attack prevention)
- Input validation (Pydantic models)
- Dependency validation (unauthorized imports blocked)
- Size limits (100KB proof code max)
**Error responses:**
- Generic messages only (no internal details)
- Error IDs for support (`err_abc123`)
- Full details in server logs
---
## Support & Resources
**Documentation:**
- API Guide: https://github.com/dirkenglund/vvuq-mcp/blob/main/API_USAGE_GUIDE.md
- Examples: https://github.com/dirkenglund/vvuq-mcp/blob/main/EXAMPLES.md (this file)
- Interactive Docs: https://vvuq.dirkenglund.org/docs (Google OAuth session, `X-API-Key`, or Bearer API key)
**Issues:**
- GitHub: https://github.com/dirkenglund/vvuq-mcp/issues
- Include error_id from error responses
**Server Status:**
- Health: https://vvuq.dirkenglund.org/health
- Quality: A+ (97/100)
- Uptime: Production deployed
---
---
## Z3 SMT Solver
### Solve SMT-LIB2 Constraints
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/z3/solve \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"smt2": "(declare-const x Int)\n(declare-const y Int)\n(assert (> x 5))\n(assert (< y 10))\n(assert (= (+ x y) 12))",
"timeout_ms": 10000
}'
```
**Response:**
```json
{
"success": true,
"verdict": "sat",
"model": {"x": "12", "y": "0"},
"execution_time_ms": 26
}
```
### JSON Convenience (No SMT-LIB2 Required)
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/z3/check \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"variables": [{"name": "x", "type": "Int"}, {"name": "y", "type": "Int"}],
"assertions": ["(> x 2)", "(< y 10)", "(= (+ x (* 2 y)) 7)"]
}'
```
### Check Unsatisfiability
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/z3/check \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"variables": [{"name": "x", "type": "Int"}],
"assertions": ["(> x 100)", "(< x 50)"]
}'
```
**Response:** `{"verdict": "unsat", "model": null}`
---
## Vision Figure Comparison
### Compare Original vs Reproduction (3 VLMs)
```bash
# Encode images as base64
ORIGINAL=$(base64 -i original_figure.png)
REPRODUCTION=$(base64 -i reproduction.png)
CODE=$(cat generate_figure.py)
curl -X POST https://vvuq.dirkenglund.org/api/v1/vision/compare \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"original_image\": \"$ORIGINAL\",
\"reproduction_image\": \"$REPRODUCTION\",
\"code\": $(echo "$CODE" | jq -Rs .)
}"
```
**Response (3 independent model evaluations):**
```json
{
"comparison_id": "cmp_abc123def456",
"success": true,
"feedbacks": [
{
"evaluation_id": "eval_111aaa222bbb",
"model": "gemma3:12b",
"success": true,
"differences": "Axis labels differ: original uses LaTeX, reproduction uses plain text...",
"suggested_changes": "- ax.set_xlabel('Wavelength')\n+ ax.set_xlabel(r'$\\lambda$ (nm)')",
"scores": {"color_accuracy": 8, "layout_accuracy": 7, "data_accuracy": 9, "overall": 8}
},
{
"evaluation_id": "eval_333ccc444ddd",
"model": "qwen3-vl",
"success": true,
"differences": "Legend position and font size differ...",
"suggested_changes": "...",
"scores": {"color_accuracy": 7, "layout_accuracy": 8, "data_accuracy": 9, "overall": 8}
},
{
"evaluation_id": "eval_555eee666fff",
"model": "llava-llama3:8b",
"success": true,
"differences": "...",
"scores": {"overall": 7}
}
],
"consensus": "## Consensus (3/3 models responded)\n**Average Scores:**\n- overall: 7.7/10"
}
```
### Submit Quality Feedback (After Testing Suggested Fixes)
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/vision/feedback \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"evaluation_id": "eval_111aaa222bbb",
"comparison_id": "cmp_abc123def456",
"rating": 4,
"code_fix_worked": true,
"comments": "LaTeX suggestion was correct, axis labels now match"
}'
```
**Response:**
```json
{
"success": true,
"feedback_id": "vfb_789ggg101hhh",
"message": "Feedback recorded for evaluation eval_111aaa222bbb"
}
```
---
## Knowledge Graph Search
### Search Topics (context7-style)
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/em/resolve \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "ring resonator design", "topic_name": "ring resonator", "limit": 5}'
```
### Get Documentation for a Topic
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/em/docs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"topic_id": "device_gap09_ring", "query": "properties and constraints"}'
```
### KG Decay Analysis
```bash
curl -X POST https://vvuq.dirkenglund.org/api/v1/kg/decay-analysis \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"label": "MathObject", "days": 30, "limit": 50}'
```
## Document Review (Compliance Checking)
VVUQ-MCP provides automated **document compliance checking** against registered rulesets. Submit structured JSON data and receive a detailed compliance report with per-rule violations, severity levels, compliance scores, and letter grades.
**Available Rulesets:**
| Ruleset ID | Description | # Rules | Tools Used |
|-----------|-------------|---------|------------|
| `nsf-biosketch` | NSF Biographical Sketch compliance | 5 | Pydantic |
| `ieee-802.3` | IEEE 802.3ck Ethernet channel compliance | 16 | Pydantic + Z3 SMT |
### NSF Biosketch Review
Submit a JSON-encoded biosketch for compliance checking against NSF formatting rules (name/ORCID required, max 10 products, professional preparation completeness, reverse chronological order, 3-page limit).
#### Compliant Biosketch (Grade A)
```bash
curl -X POST https://vvuq.dirkenglund.org/review/submit \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "{\"name\":\"Jane Smith\",\"orcid\":\"0000-0001-2345-6789\",\"products_closely_related\":[{\"title\":\"Paper A\",\"year\":2023},{\"title\":\"Paper B\",\"year\":2022}],\"products_other\":[{\"title\":\"Paper C\",\"year\":2021}],\"professional_preparation\":[{\"institution\":\"MIT\",\"degree\":\"PhD\",\"field\":\"Physics\",\"year\":2018}],\"appointments\":[{\"title\":\"Professor\",\"institution\":\"Stanford\",\"start_year\":2020},{\"title\":\"Postdoc\",\"institution\":\"MIT\",\"start_year\":2018}]}",
"content_type": "json",
"ruleset_ids": ["nsf-biosketch"]
}'
```
**Expected Response:**
```json
{
"review_id": "rev_...",
"status": "completed",
"result": {
"violations": [],
"total_violations": 0,
"compliance_score": 1.0,
"grade": "A",
"critical_count": 0,
"high_count": 0,
"medium_count": 0,
"low_count": 0
}
}
```
#### Non-Compliant Biosketch (Missing Fields)
```bash
curl -X POST https://vvuq.dirkenglund.org/review/submit \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "{\"name\":\"\",\"products_closely_related\":[{\"title\":\"A\"},{\"title\":\"B\"},{\"title\":\"C\"},{\"title\":\"D\"},{\"title\":\"E\"},{\"title\":\"F\"}],\"products_other\":[{\"title\":\"G\"},{\"title\":\"H\"},{\"title\":\"I\"},{\"title\":\"J\"},{\"title\":\"K\"}],\"professional_preparation\":[{\"institution\":\"MIT\"}],\"appointments\":[{\"title\":\"Postdoc\",\"start_year\":2018},{\"title\":\"Professor\",\"start_year\":2020}]}",
"content_type": "json",
"ruleset_ids": ["nsf-biosketch"]
}'
```
**Expected Violations:**
- `NSF:name-and-orcid-required` (critical) ā empty name + missing ORCID
- `NSF:product-count-max-10` (critical) ā 11 products exceed 10 maximum
- `NSF:professional-preparation-complete` (high) ā missing degree/field/year
- `NSF:reverse-chronological-order` (medium) ā 2018 before 2020
### IEEE 802.3 Ethernet Channel Review
Submit IEEE 802.3ck channel measurement data (S-parameters, eye diagrams, jitter budgets, COM) for compliance checking. Uses **Z3 SMT solver** for constraint checks involving interdependent physical quantities.
**16 rules checked:**
- 8 threshold checks (Pydantic): COM, insertion loss, return loss, TDECQ, eye height/width, TX amplitude, impedance
- 4 constraint checks (Z3): jitter budget decomposition, S-parameter passivity, reciprocity, COM budget allocation
- 4 data integrity checks: causality verification, frequency coverage validation, cross-field consistency, data integrity (array lengths, monotonic frequencies, non-negative values)
#### Compliant 100G PAM4 Channel (Grade A)
```bash
curl -X POST https://vvuq.dirkenglund.org/review/submit \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "{\"channel_id\":\"link_01\",\"data_rate_gbps\":106.25,\"modulation\":\"PAM4\",\"com_db\":3.5,\"insertion_loss_db\":[0.5,1.2,2.8,5.1,8.0,12.5,18.0,25.0],\"return_loss_db\":[25.0,22.0,18.5,15.0,13.5,12.5,12.1,12.0],\"frequencies_ghz\":[1.0,5.0,10.0,15.0,20.0,25.0,30.0,35.0],\"eye_height_mv\":18.0,\"eye_width_ui\":0.35,\"tdecq_db\":3.1,\"tx_amplitude_mv\":800,\"jitter\":{\"tj_ui\":0.25,\"dj_ui\":0.10,\"rj_rms_ui\":0.008},\"s_parameters\":{\"passivity_margin\":0.001,\"reciprocity_error\":0.005,\"causality_ok\":true},\"impedance_ohm\":99.5}",
"content_type": "json",
"ruleset_ids": ["ieee-802.3"]
}'
```
**Expected Response:**
```json
{
"review_id": "rev_...",
"status": "completed",
"result": {
"violations": [],
"total_violations": 0,
"compliance_score": 1.0,
"grade": "A",
"critical_count": 0,
"high_count": 0,
"medium_count": 0,
"low_count": 0
}
}
```
#### Non-Compliant Channel (Grade F ā Multiple Failures)
```bash
curl -X POST https://vvuq.dirkenglund.org/review/submit \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "{\"channel_id\":\"bad_link\",\"data_rate_gbps\":106.25,\"modulation\":\"PAM4\",\"com_db\":2.0,\"insertion_loss_db\":[1.0,5.0,15.0,30.0,40.0,50.0,55.0,60.0],\"return_loss_db\":[20.0,15.0,10.0,8.0,6.0,5.0,4.0,3.0],\"frequencies_ghz\":[1.0,5.0,10.0,15.0,20.0,25.0,30.0,35.0],\"eye_height_mv\":10.0,\"eye_width_ui\":0.20,\"tdecq_db\":4.0,\"tx_amplitude_mv\":300,\"jitter\":{\"tj_ui\":0.50,\"dj_ui\":0.30,\"rj_rms_ui\":0.02},\"s_parameters\":{\"passivity_margin\":-0.05,\"reciprocity_error\":0.15,\"causality_ok\":false},\"impedance_ohm\":120.0}",
"content_type": "json",
"ruleset_ids": ["ieee-802.3"]
}'
```
**Expected Violations (16 total):**
| Rule ID | Severity | Evidence |
|---------|----------|----------|
| `IEEE802.3:com-minimum` | critical | COM = 2.0 dB < 3.0 dB minimum |
| `IEEE802.3:insertion-loss-budget` | critical | Max IL = 60.0 dB > 35.0 dB budget |
| `IEEE802.3:return-loss-minimum` | high | Min RL = 3.0 dB < 12.0 dB minimum |
| `IEEE802.3:tdecq-limit` | critical | TDECQ = 4.0 dB > 3.4 dB maximum |
| `IEEE802.3:eye-height-minimum` | critical | Eye height = 10.0 mV < 15.0 mV |
| `IEEE802.3:eye-width-minimum` | high | Eye width = 0.20 UI < 0.3 UI |
| `IEEE802.3:tx-amplitude-range` | high | TX = 300 mV, range 400-1200 mV |
| `IEEE802.3:impedance-range` | high | Z = 120 ohm, range 90-110 ohm |
| `IEEE802.3:jitter-budget` | critical | TJ inconsistent with DJ + k*RJ |
| `IEEE802.3:s-param-passivity` | critical | Margin = -0.05 (energy creation) |
| `IEEE802.3:s-param-reciprocity` | high | Error = 0.15 > 0.05 threshold |
| `IEEE802.3:com-budget-allocation` | medium | COM + IL exceeds link budget |
| `IEEE802.3:causality-check` | critical | Non-causal impulse response (causality_ok=False) |
| `IEEE802.3:frequency-coverage` | high | Frequency range below Nyquist for data rate |
| `IEEE802.3:cross-field-consistency` | medium | Low COM with high eye height is inconsistent |
| `IEEE802.3:data-integrity` | critical | Non-positive data rate or array length mismatch |
#### IEEE 802.3 Channel Data Schema
```json
{
"channel_id": "string (required)",
"data_rate_gbps": "float > 0 (required)",
"modulation": "NRZ | PAM4 (required)",
"com_db": "float (required) ā Channel Operating Margin in dB",
"insertion_loss_db": "[float] (required) ā IL vs frequency in dB",
"return_loss_db": "[float] (required) ā RL vs frequency in dB",
"frequencies_ghz": "[float] (required) ā frequency points in GHz",
"eye_height_mv": "float (required) ā eye height in mV",
"eye_width_ui": "float (required) ā eye width in UI",
"tdecq_db": "float | null ā TDECQ in dB (required for PAM4)",
"tx_amplitude_mv": "float > 0 (required) ā TX amplitude in mV",
"jitter": {
"tj_ui": "float >= 0 ā total jitter in UI",
"dj_ui": "float >= 0 ā deterministic jitter in UI",
"rj_rms_ui": "float >= 0 ā random jitter RMS in UI"
},
"s_parameters": {
"passivity_margin": "float ā min(1 - |S11|^2 - |S21|^2)",
"reciprocity_error": "float >= 0 ā max |S12 - S21|",
"causality_ok": "bool ā impulse response causal"
},
"impedance_ohm": "float > 0 ā differential impedance in ohm"
}
```
**Note:** All frequency-domain arrays (`insertion_loss_db`, `return_loss_db`, `frequencies_ghz`) must have the same length.
### Review Response Structure
All document reviews return the same response structure:
```json
{
"review_id": "rev_",
"status": "completed",
"result": {
"violations": [
{
"rule_id": "RULESET:rule-name",
"severity": "critical|high|medium|low",
"evidence": "Human-readable explanation",
"field_path": "dot.separated.path"
}
],
"total_violations": 0,
"compliance_score": 1.0,
"grade": "A|B|C|D|F",
"critical_count": 0,
"high_count": 0,
"medium_count": 0,
"low_count": 0
}
}
```
**Grading Scale:**
- **A**: compliance >= 0.9
- **B**: compliance >= 0.75
- **C**: compliance >= 0.6
- **D**: compliance >= 0.4
- **F**: compliance < 0.4
---
**Last Updated:** 2026-02-23
**API Version:** see the live [`/health`](https://vvuq.dirkenglund.org/health) endpoint (derived from package metadata)
**All examples tested:** Validated against production API