Metadata-Version: 2.4
Name: minicrit
Version: 0.3.2
Summary: Adversarial AI validation for autonomous systems - catch reasoning flaws before they become failures
Author-email: William Alexander Ousley <founders@antagon.ai>, Jacqueline Villamor Ousley <founders@antagon.ai>
Maintainer-email: "Antagon Inc." <founders@antagon.ai>
License: Apache-2.0
Project-URL: Homepage, https://antagon.ai
Project-URL: Documentation, https://github.com/antagoninc/MiniCrit-7B/tree/main/docs
Project-URL: Repository, https://github.com/antagoninc/MiniCrit-7B
Project-URL: Issues, https://github.com/antagoninc/MiniCrit-7B/issues
Project-URL: Changelog, https://github.com/antagoninc/MiniCrit-7B/blob/main/CHANGELOG.md
Keywords: ai-safety,adversarial-ai,llm,validation,trading,defense,reasoning,critique,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Security
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: torch>=2.0.0
Requires-Dist: transformers>=4.40.0
Requires-Dist: peft>=0.10.0
Requires-Dist: accelerate>=0.25.0
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == "mcp"
Requires-Dist: fastapi>=0.109.0; extra == "mcp"
Requires-Dist: uvicorn>=0.27.0; extra == "mcp"
Provides-Extra: server
Requires-Dist: fastapi>=0.109.0; extra == "server"
Requires-Dist: uvicorn>=0.27.0; extra == "server"
Requires-Dist: python-jose>=3.3.0; extra == "server"
Provides-Extra: redis
Requires-Dist: redis>=5.0.0; extra == "redis"
Provides-Extra: observability
Requires-Dist: opentelemetry-api>=1.20.0; extra == "observability"
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "observability"
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == "observability"
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.41b0; extra == "observability"
Requires-Dist: opentelemetry-instrumentation-httpx>=0.41b0; extra == "observability"
Provides-Extra: training
Requires-Dist: datasets>=2.16.0; extra == "training"
Requires-Dist: wandb>=0.16.0; extra == "training"
Requires-Dist: trl>=0.7.0; extra == "training"
Requires-Dist: anthropic>=0.18.0; extra == "training"
Provides-Extra: eval
Requires-Dist: rouge-score>=0.1.2; extra == "eval"
Requires-Dist: bert-score>=0.3.13; extra == "eval"
Requires-Dist: pandas>=2.0.0; extra == "eval"
Requires-Dist: numpy>=1.24.0; extra == "eval"
Provides-Extra: all
Requires-Dist: minicrit[eval,mcp,observability,redis,server,training]; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: httpx>=0.25.0; extra == "dev"
Requires-Dist: langchain-core>=0.1.0; extra == "dev"

# MiniCrit-7B: Adversarial AI Validation for Autonomous Systems

<p align="center">
  <img src="assets/minicrit_logo.png" alt="MiniCrit Logo" width="200">
</p>

<p align="center">
  <strong>🛡️ Catch AI reasoning flaws before they become failures</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/minicrit/"><img src="https://img.shields.io/pypi/v/minicrit?color=blue&label=PyPI" alt="PyPI"></a>
  <a href="https://huggingface.co/wmaousley/MiniCrit-7B"><img src="https://img.shields.io/badge/🤗%20HuggingFace-MiniCrit--7B-blue" alt="HuggingFace"></a>
  <a href="https://github.com/antagoninc/MiniCrit-7B/actions"><img src="https://img.shields.io/badge/Tests-489%20Passing-brightgreen" alt="Tests"></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-red" alt="License"></a>
  <a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-Compatible-purple" alt="MCP"></a>
</p>

<p align="center">
  <a href="#quick-start">Quick Start</a> •
  <a href="#mcp-integration">MCP Integration</a> •
  <a href="#openai-compatible-api">OpenAI API</a> •
  <a href="#langchain-integration">LangChain</a> •
  <a href="#training">Training</a> •
  <a href="#benchmarks">Benchmarks</a>
</p>

---

## 🎯 The Problem

Autonomous AI systems fail silently. They produce confident-sounding outputs with hidden flaws—overconfidence, missing risks, logical errors, hallucinations. **By the time you notice, it's too late.**

Traditional testing catches bugs. **MiniCrit catches bad reasoning.**

## 💡 The Solution

MiniCrit is a specialized AI "devil's advocate" that validates reasoning **before** actions are taken. It integrates with any AI system via MCP (Model Context Protocol) to provide real-time adversarial critique.

```
Your AI Agent → MiniCrit Validation → Safer Decisions
     ↓                   ↓                    ↓
  "Buy AAPL,         "Overconfidence:      Execute with
   95% confident"     only 2 data points,   reduced size
                      missing earnings       or skip
                      risk"
```

---

## 📊 Results and evaluation status

> **Read this before relying on any MiniCrit output.**
>
> - The checkpoint published at `wmaousley/MiniCrit-7B` (Qwen2-7B-Instruct base) is a **research checkpoint at 9.8% of planned training** and has **not been evaluated** on held-out benchmarks.
> - Antagon's only measured MiniCrit result (21/21 seeded flaws detected, 0/21 false positives on a 42-item set, greedy decoding) belongs to a **different, unpublished adapter** on `mistralai/Mistral-7B-v0.1`. It does not describe this package's default model.
> - Performance figures previously shown here (F1, false-positive rate, latency, Sharpe-ratio and false-signal improvements, live-validation counts, and comparisons with other models) have been withdrawn until they can be republished with the measurement record they came from: model artifact, dataset, decoding settings and method.
> - In responses, `confidence` is `null` (not yet produced by the model), `valid` is `null`, and `severity` comes from a keyword heuristic over the critique text (`severity_basis: "keyword_heuristic"`). See **Output Format**.

---

## 🚀 Quick Start

### Option 1: pip install (Recommended)

```bash
pip install minicrit
```

```python
from minicrit import MiniCrit

# Initialize (downloads model automatically)
critic = MiniCrit()

# Validate reasoning
result = critic.validate(
    "Stock will rise because it rose yesterday",
    domain="trading"
)

print(result.valid)      # False
print(result.severity)   # "high" 
print(result.critique)   # "This reasoning exhibits recency bias..."
print(result.flags)      # ["overconfidence", "insufficient_evidence"]
```

### Option 2: CLI

```bash
# Single validation
minicrit "Buy AAPL, 95% confident" --domain trading

# From file
minicrit --file rationales.txt --output results.json

# JSON output
minicrit "MACD crossover signals buy" --json
```

### Installation Extras

```bash
# Core only
pip install minicrit

# With MCP server support
pip install minicrit[mcp]

# With training utilities
pip install minicrit[training]

# Everything
pip install minicrit[all]
```

### Option 3: Docker

```bash
cd docker
docker-compose up -d
curl http://localhost:8000/critique \
  -H "Content-Type: application/json" \
  -d '{"rationale": "Buy signal based on MACD crossover", "domain": "trading"}'
```

### Option 4: MCP (Claude Desktop / Claude Code)

```json
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "minicrit": {
      "command": "python3",
      "args": ["/path/to/MiniCrit-7B/src/mcp/server.py"],
      "env": {
        "MINICRIT_ADAPTER": "wmaousley/MiniCrit-7B",
        "MINICRIT_BASE_MODEL": "Qwen/Qwen2-7B-Instruct"
      }
    }
  }
}
```

Then in Claude: *"Use validate_reasoning to check: Buy AAPL, RSI shows oversold"*

---

## 🔌 MCP Integration

MiniCrit implements the **Model Context Protocol** (MCP)—the industry standard for AI tool integration, backed by Anthropic, OpenAI, Google, and Microsoft.

**Any MCP-compatible AI can call MiniCrit:**

```
┌─────────────────┐         ┌─────────────────┐
│  Claude / GPT   │         │    MiniCrit     │
│  Gemini / etc.  │◄───────►│   MCP Server    │
└─────────────────┘   MCP   └─────────────────┘
         │                           │
         │    Tool: validate_reasoning
         │    Input: {rationale, domain}
         │    Output: {valid, severity, critique, flags}
         │
         ▼
   Safer AI Decisions
```

### MCP Server Options

| Server | Use Case | Command |
|--------|----------|---------|
| `server.py` | Claude Desktop / Claude Code (stdio) | `python -m src.mcp.server` |
| `server_http.py` | Basic HTTP API | `python -m src.mcp.server_http` |
| `server_prod.py` | Production with auth & rate limiting | `python -m src.mcp.server_prod` |

### Claude Desktop Setup

```json
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "minicrit": {
      "command": "python3",
      "args": ["-m", "src.mcp.server"],
      "cwd": "/path/to/MiniCrit-7B",
      "env": {
        "MINICRIT_ADAPTER": "wmaousley/MiniCrit-7B",
        "MINICRIT_BASE_MODEL": "Qwen/Qwen2-7B-Instruct",
        "MINICRIT_PRELOAD": "true"
      }
    }
  }
}
```

### Production HTTP Server

```bash
# Start with API key authentication
export MINICRIT_API_KEYS="key1,key2,key3"
export MINICRIT_RATE_LIMIT=60  # requests per minute
python -m src.mcp.server_prod

# Or with gunicorn for production
gunicorn src.mcp.server_prod:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
```

**Production endpoints:**

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/health` | GET | Health check (no auth) |
| `/info` | GET | Server info and rate limits |
| `/validate` | POST | Validate single reasoning |
| `/batch` | POST | Batch validate (up to 100 items) |
| `/sse` | GET | MCP Server-Sent Events stream |
| `/admin/keys` | POST | Create API key (admin only) |
| `/admin/audit` | GET | View audit log (admin only) |
| `/admin/stats` | GET | Usage statistics (admin only) |

### MCP Tools

| Tool | Description |
|------|-------------|
| `validate_reasoning` | Validate AI reasoning, returns critique with severity |
| `batch_validate` | Validate multiple items efficiently (max 100) |
| `get_model_info` | Get model status, device, and statistics |

### Programmatic Usage

```python
from src.mcp import (
    ModelManager,
    CritiqueGenerator,
    CritiqueResult,
    InputSanitizer,
    get_model_manager,
    get_critique_generator,
)

# Singleton model manager (thread-safe)
manager = ModelManager.get_instance()

# Generate critiques
generator = CritiqueGenerator(manager)
result = generator.generate(
    rationale="AAPL will rise because momentum is positive",
    domain="trading",
    context="Portfolio allocation decision"
)

print(result.valid)       # False
print(result.severity)    # "high"
print(result.critique)    # "This reasoning exhibits..."
print(result.flags)       # ["overconfidence", "insufficient_evidence"]
print(result.latency_ms)  # 42.3

# Async version
result = await generator.generate_async(
    rationale="Buy signal based on MACD crossover",
    domain="trading"
)
```

### Supported Domains

`trading` • `finance` • `defense` • `cybersecurity` • `medical` • `risk_assessment` • `resource_allocation` • `planning_scheduling` • `general`

### Output Format

```json
{
  "valid": null,
  "valid_keyword_heuristic": false,
  "severity": "high",
  "severity_basis": "keyword_heuristic",
  "critique": "This reasoning exhibits recency bias. A single day's price movement has no predictive power...",
  "confidence": null,
  "confidence_source": "not_emitted",
  "flags": ["overconfidence", "insufficient_evidence", "missing_consideration"],
  "domain": "trading",
  "decoding": {"max_new_tokens": 256, "do_sample": false, "repetition_penalty": 1.15},
  "latency_ms": 42.3,
  "request_id": "req_abc123"
}
```

`confidence` will be populated from the model once it emits the structured format defined in Antagon's output contract v1. Until then it is `null` rather than an estimate. `severity` is matched from keywords in the critique without handling negation ("no critical flaw" matches *critical*), so treat it as a hint, not a verdict.

**Severity Levels:** `pass` → `low` → `medium` → `high` → `critical`

**Common Flags:**
- `overconfidence` - Certainty without sufficient evidence
- `missing_consideration` - Key factors not addressed
- `logical_inconsistency` - Contradictions in reasoning
- `insufficient_evidence` - Claims lack support
- `unaddressed_risk` - Potential risks not considered

---

## 🌐 OpenAI-Compatible API

MiniCrit provides an OpenAI-compatible API server, allowing drop-in replacement for any OpenAI client:

### Start the Server

```bash
# Start the OpenAI-compatible server
python -m src.openai_compat_server

# Or with uvicorn for production
uvicorn src.openai_compat_server:app --host 0.0.0.0 --port 8080
```

### Use with Any OpenAI Client

```python
from openai import OpenAI

# Point to MiniCrit server
client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="minicrit"  # Any string works
)

response = client.chat.completions.create(
    model="minicrit-7b",
    messages=[
        {"role": "user", "content": "AAPL is bullish because momentum is positive"}
    ],
    temperature=0.7,
    max_tokens=512
)

print(response.choices[0].message.content)
```

### Endpoints

| Endpoint | Description |
|----------|-------------|
| `GET /health` | Health check with model status |
| `GET /v1/models` | List available models |
| `GET /v1/models/{id}` | Get specific model info |
| `POST /v1/chat/completions` | Generate critique (streaming supported) |

### Streaming

```python
# Stream responses
stream = client.chat.completions.create(
    model="minicrit-7b",
    messages=[{"role": "user", "content": "Validate this reasoning..."}],
    stream=True
)

for chunk in stream:
    print(chunk.choices[0].delta.content, end="")
```

---

## 🦜 LangChain Integration

MiniCrit integrates seamlessly with LangChain for building AI pipelines:

### Installation

```bash
pip install minicrit langchain-core
```

### Basic Usage

```python
from langchain_minicrit import MiniCritLLM, MiniCritChat, MiniCritValidator

# As an LLM
llm = MiniCritLLM(base_url="http://localhost:8080/v1")
critique = llm.invoke("Stock will rise due to momentum")
print(critique)

# As a Chat Model
from langchain_core.messages import HumanMessage, SystemMessage

chat = MiniCritChat(base_url="http://localhost:8080/v1")
response = chat.invoke([
    SystemMessage(content="You are a financial reasoning critic."),
    HumanMessage(content="Buy AAPL because it went up yesterday")
])
print(response.content)
```

### Validation Chain

```python
from langchain_minicrit import MiniCritValidator

validator = MiniCritValidator(
    base_url="http://localhost:8080/v1",
    threshold=70.0  # Minimum score to pass
)

result = validator.validate("MACD crossover signals a buy opportunity")

print(f"Valid: {result.is_valid}")
print(f"Score: {result.score}")
print(f"Critique: {result.critique}")
print(f"Flaws: {[f.antagon_flaw_id for f in result.flaws]}")
```

### In LangChain Pipelines

```python
from langchain_core.runnables import RunnablePassthrough
from langchain_minicrit import MiniCritValidationChain

# Create validation chain
validator = MiniCritValidationChain(threshold=70.0)

# Compose with other runnables
pipeline = RunnablePassthrough() | validator

result = pipeline.invoke("High confidence trade based on sentiment analysis")
```

---

## 🔍 What MiniCrit Detects

<table>
<tr>
<td width="50%">

### Cognitive Biases
- ⚠️ **Overconfidence** - Certainty without evidence
- ⚠️ **Survivorship Bias** - Ignoring failures
- ⚠️ **Confirmation Bias** - Cherry-picking data
- ⚠️ **Anchoring** - Over-relying on first info
- ⚠️ **Recency Bias** - Overweighting recent events

</td>
<td width="50%">

### Logical Flaws
- 🚫 **False Causation** - Correlation ≠ causation
- 🚫 **Hasty Generalization** - Small sample size
- 🚫 **Missing Risks** - Unaddressed threats
- 🚫 **Circular Reasoning** - Assuming the conclusion
- 🚫 **False Dichotomy** - Ignoring options

</td>
</tr>
</table>

### Example

**Input:**
> "AAPL long: The stock has risen 3 days in a row, momentum is clearly bullish. 95% confident this continues."

**MiniCrit Output:**
> ⚠️ **HIGH SEVERITY** - Multiple reasoning flaws detected:
> 
> 1. **Overconfidence**: 95% confidence is not supported by the evidence provided
> 2. **Recency Bias**: 3 days of price movement has minimal predictive value
> 3. **Missing Risk Factors**: No consideration of upcoming earnings, macro events, or sector rotation
> 
> *Flags: overconfidence, insufficient_evidence, unaddressed_risk*

---

## 🏗️ Architecture

```
┌──────────────────────────────────────────────────────────────────┐
│                      MiniCrit-7B System                          │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌────────────┐    ┌─────────────┐    ┌───────────────────────┐ │
│  │ AI System  │───▶│   MiniCrit  │───▶│   Validated Output    │ │
│  │ (Any LLM)  │    │   Server    │    │                       │ │
│  └────────────┘    └──────┬──────┘    │ • valid: null (interim)│ │
│                           │           │ • severity: enum      │ │
│                    ┌──────▼──────┐    │ • critique: string    │ │
│                    │  Qwen2-7B   │    │ • flags: list         │ │
│                    │    Base     │    │ • confidence: null    │ │
│                    └──────┬──────┘    └───────────────────────┘ │
│                           │                                      │
│                    ┌──────▼──────┐                              │
│                    │   LoRA      │  40.4M trainable params      │
│                    │  Adapter    │  LoRA on CritiqueBank-11M (9.8% of planned steps)  │
│                    └─────────────┘                              │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘
```

---

## 📈 Training

### Model Specifications

| Parameter | Value |
|-----------|-------|
| Base Model | `Qwen/Qwen2-7B-Instruct` |
| Method | LoRA (r=16, α=32) |
| Trainable Params | 40.4M / 7.6B (0.5%) |
| Dataset | CritiqueBank-11M |
| Hardware | Lambda Labs H100 PCIe (80GB) |
| Training Loss | 3.19 → 0.44 (86% reduction) |

### Dataset: CritiqueBank-11M

| Property | Value |
|----------|-------|
| Rows | 11,674,598 |
| Distinct rationales | **215** (43 tickers x 5 indicator templates) |
| Domain | Financial trading signals, `long` only |
| Labelled critique styles | 6 (timing, contrarian, logical_flaw, adversarial, risk_emphasis, contextual) |
| Generator | Google Gemini Flash. No human annotation |

The variation is on the critique side; the rationale side is a closed set of 215
inputs. A model trained on this has seen 215 distinct inputs and should not be
assumed to generalise to unseen rationale forms without evaluation on
independently generated data. See the dataset card for the full composition.

> **Correction.** Earlier versions of this README described the dataset as five
> named components (LogicFlaw, FactCheck, BiasDetect, RiskMissing,
> DomainSpecific) spanning trading, defense and medical domains. No such
> components or domains exist in the deposited data, which is single-domain. The
> table above is the measured composition.

**Published:** [DOI 10.5281/zenodo.23091964](https://doi.org/10.5281/zenodo.23091964)
(supersedes 10.5281/zenodo.18159342)

### Training Progress

```
Loss
3.2 │██
2.4 │  ████
1.6 │      ██████
0.8 │            ████████████
0.4 │                        ████████████████  ← Current
    └─────────────────────────────────────────
    0%        25%        50%        75%     100%
```

### Run Training

```bash
# Lambda Labs (H100)
python train_minicrit_7b.py --config configs/7b_lora.yaml
```

---

## 🧪 Benchmarking

Compare MiniCrit models head-to-head:

```bash
python src/benchmark/benchmark_models.py \
  --eval-data data/eval_holdout.jsonl \
  --model-1 wmaousley/MiniCrit-1.5B \
  --model-2 wmaousley/MiniCrit-7B \
  --judge-sample 200  # Optional: LLM-as-judge comparison
```

### Metrics Computed

| Metric | Description |
|--------|-------------|
| False Positive Rate | Valid reasoning incorrectly flagged |
| Detection F1 | Precision/recall on flaw detection |
| Latency (p50/p95/p99) | Inference speed percentiles |
| LLM Judge Score | Claude rates critique quality |

---

## 🔧 Advanced: Improve Your Model

### Generate Hard Training Examples

```bash
# Uses Claude Sonnet (~$30 for 5K examples)
export ANTHROPIC_API_KEY=your-key
python src/training/generate_hard_examples.py --count 5000
```

### Direct Preference Optimization (DPO)

```bash
# Generate preference pairs
python src/training/generate_dpo_data.py \
  --input eval_holdout.jsonl \
  --model wmaousley/MiniCrit-7B \
  --output dpo_pairs.jsonl

# Run DPO training
python src/training/train_dpo.py \
  --model wmaousley/MiniCrit-7B \
  --data dpo_pairs.jsonl \
  --output minicrit-7b-dpo
```

See [docs/MODEL_EXCELLENCE_GUIDE.md](docs/MODEL_EXCELLENCE_GUIDE.md) for the full improvement roadmap.

---

## 📁 Repository Structure

```
MiniCrit-7B/
├── src/
│   ├── mcp/                    # MCP Server Implementation
│   │   ├── core.py             # Thread-safe ModelManager, CritiqueGenerator
│   │   ├── server.py           # Local stdio (Claude Desktop)
│   │   ├── server_prod.py      # Production HTTP + auth + rate limiting
│   │   └── server_http.py      # Basic HTTP server
│   ├── benchmark/              # Model Evaluation
│   │   └── benchmark_models.py
│   ├── training/               # Training Utilities
│   │   ├── generate_hard_examples.py
│   │   ├── generate_dpo_data.py
│   │   └── train_dpo.py
│   ├── openai_compat_server.py # OpenAI-compatible API
│   ├── config.py
│   ├── data.py
│   ├── model.py
│   ├── training.py
│   ├── evaluation.py
│   └── api.py
├── langchain_minicrit/         # LangChain Integration
│   ├── __init__.py
│   ├── llm.py                  # LLM wrapper
│   ├── chat.py                 # Chat model
│   ├── validator.py            # Validation chain
│   └── callbacks.py            # Callback handlers
├── docker/
│   ├── Dockerfile
│   ├── docker-compose.yml
│   └── requirements.txt
├── configs/
│   ├── claude_desktop_config.json
│   ├── 7b_lora.yaml
│   └── deepspeed_gh200.json
├── scripts/
├── tests/                      # 489 tests
├── docs/
│   ├── DEPLOYMENT_GUIDE.md
│   └── MODEL_EXCELLENCE_GUIDE.md
└── CHANGELOG.md
```

---

## 🐳 Deployment Options

### Docker (Recommended)

```bash
cd docker
cp .env.example .env
# Edit .env with your settings
docker-compose up -d
```

### Kubernetes

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: minicrit
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: minicrit
        image: antagoninc/minicrit:latest
        resources:
          limits:
            nvidia.com/gpu: 1
```

### Production HTTP Server

```bash
# With authentication & rate limiting
export MINICRIT_API_KEYS="key1,key2,key3"
python src/mcp/server_prod.py
```

See [docs/DEPLOYMENT_GUIDE.md](docs/DEPLOYMENT_GUIDE.md) for complete instructions.

---

## ⚙️ Configuration

### Environment Variables

**Model Configuration:**

| Variable | Default | Description |
|----------|---------|-------------|
| `MINICRIT_ADAPTER` | `wmaousley/MiniCrit-7B` | HuggingFace adapter path |
| `MINICRIT_BASE_MODEL` | `Qwen/Qwen2-7B-Instruct` | Base model path |
| `MINICRIT_DEVICE` | `auto` | Device: `auto`, `cuda`, `mps`, `cpu` |
| `MINICRIT_QUANTIZATION` | `none` | Quantization: `none`, `8bit`, `4bit` |
| `MINICRIT_MAX_LENGTH` | `512` | Max input sequence length |
| `MINICRIT_INFERENCE_TIMEOUT` | `120` | Inference timeout in seconds |
| `MINICRIT_PRELOAD` | `false` | Preload model on server startup |
| `MINICRIT_LOG_LEVEL` | `INFO` | Logging level |

**Production Server (`server_prod.py`):**

| Variable | Default | Description |
|----------|---------|-------------|
| `MINICRIT_PORT` | `8000` | Server port |
| `MINICRIT_API_KEYS` | - | Comma-separated valid API keys |
| `MINICRIT_MASTER_KEY` | (random) | Admin master key |
| `MINICRIT_RATE_LIMIT` | `60` | Requests per minute per key |
| `MINICRIT_CORS_ORIGINS` | `localhost:3000,8080` | Allowed CORS origins |
| `MINICRIT_LOG_REQUESTS` | `true` | Log all requests |
| `REDIS_URL` | - | Redis URL for distributed rate limiting |

**Rate Limit Tiers:**

| Tier | Requests/Min | Description |
|------|-------------|-------------|
| `free` | 10 | Anonymous/unauthenticated |
| `standard` | 60 | Default API key tier |
| `premium` | 300 | Premium API keys |
| `admin` | 1000 | Master key |

### 8-bit / 4-bit Quantization

MiniCrit supports quantization via `bitsandbytes` to reduce memory usage:

```bash
# 8-bit quantization (~50% memory reduction)
export MINICRIT_QUANTIZATION=8bit
python -m src.mcp.server

# 4-bit quantization (~75% memory reduction, slight quality loss)
export MINICRIT_QUANTIZATION=4bit
python -m src.mcp.server
```

**Requirements:**
- `bitsandbytes>=0.41.0` (included in dependencies)
- CUDA-capable GPU
- Falls back to fp16 gracefully if bitsandbytes is unavailable

### Input Sanitization (Security)

MiniCrit includes built-in input sanitization to protect against prompt injection attacks:

- **Injection Pattern Detection**: Blocks patterns like "ignore previous instructions", "system:", etc.
- **Control Character Removal**: Strips null bytes, zero-width chars, and other control characters
- **Length Validation**: Enforces max 50,000 character rationales, 100 char domains
- **Domain Whitelisting**: Only accepts valid domains from the supported list

```python
from minicrit import InputSanitizer, InputSanitizationError

sanitizer = InputSanitizer()
try:
    clean_input = sanitizer.validate_rationale(user_input)
except InputSanitizationError as e:
    print(f"Blocked: {e}")
```

---

## 🎯 Use Cases

| Domain | Application |
|--------|-------------|
| **Quantitative Trading** | Validate signals before execution |
| **Defense / Intelligence** | Audit AI threat assessments |
| **Medical AI** | Review diagnostic reasoning |
| **Autonomous Vehicles** | Validate planning decisions |
| **Enterprise AI** | Catch hallucinations before they propagate |

---

## 📜 Citation

```bibtex
@software{minicrit2026,
  author = {Ousley, William Alexander and Ousley, Jacqueline Villamor},
  title = {MiniCrit: Adversarial AI Validation for Autonomous Systems},
  year = {2026},
  publisher = {Antagon Inc.},
  url = {https://github.com/antagoninc/MiniCrit-7B}
}
```

---

## 🙏 Acknowledgments

<p align="center">
  <a href="https://lambdalabs.com"><img src="https://img.shields.io/badge/GPU%20Compute-Lambda%20Labs-purple" alt="Lambda Labs"></a>
</p>

- **Lambda Labs** - GPU compute grant for H100 training
- **Anthropic** - MCP standard development

No high-performance computing facility and no federal funding of any kind
supported this work.

---

## 📄 License

Apache 2.0 - See [LICENSE](LICENSE)

---

<p align="center">
  <b>Antagon Inc.</b><br>
  Making AI Systems Safer Through Adversarial Testing
</p>

<p align="center">
  <a href="https://antagon.ai">Website</a> •
  <a href="mailto:founders@antagon.ai">Contact</a> •
  CAGE: 17E75 • UEI: KBSGT7CZ4AH3
</p>

<p align="center">
  <b>William Alexander Ousley</b> - Co-Founder & CEO<br>
  <b>Jacqueline Villamor Ousley</b> - Co-Founder & CTO
</p>
