# Migration Guide: v1 to v2 (Thin Middleware)

This guide covers migrating from LockStock Integrations v1.x (Guard daemon + local crypto) to v2.x (thin SaaS middleware).

## Overview

| Feature | v1.x (LockStockMiddleware) | v2.x (LockStockThinMiddleware) |
|---------|---------------------------|-------------------------------|
| Daemon required | Yes (Guard daemon) | No |
| Local crypto | Yes (HMAC signing) | No (server handles all) |
| SSE streaming | Limited (response buffering) | Full support (pure ASGI) |
| Authentication | Unix socket + chain sync | API key (Bearer token) |
| Complexity | High (daemon lifecycle) | Low (just HTTP calls) |

## When to Migrate

**Migrate to v2 if:**
- You're deploying to serverless/container environments
- You need reliable SSE streaming for LLM responses
- You want simpler deployment (no daemon to manage)
- You're okay with API key authentication

**Stay on v1 if:**
- You need hardware-bound security (TPM/HSM)
- You're running air-gapped/offline
- You need the two-party verification protocol

## Migration Steps

### 1. Update Dependencies

```bash
# Old
pip install lockstock-integrations[guard,fastapi]

# New
pip install lockstock-integrations[fastapi]
```

### 2. Get API Key

Log into the LockStock dashboard and create an API key for your agent:

1. Go to **Settings > API Keys**
2. Click **Create Key**
3. Select scope: `stamp:write`
4. Copy the key (starts with `lsk_admin_`)

### 3. Update Middleware Configuration

**Before (v1):**
```python
from fastapi import FastAPI
from lockstock_fastapi import LockStockMiddleware

app = FastAPI()

app.add_middleware(
    LockStockMiddleware,
    agent_id="agent_abc123",
    guard_socket="/var/run/lockstock-guard/guard.sock",
    server_endpoint="https://lockstock-api-i9kp.onrender.com",
)
```

**After (v2):**
```python
from fastapi import FastAPI
from lockstock_fastapi import LockStockThinMiddleware

app = FastAPI()

app.add_middleware(
    LockStockThinMiddleware,
    agent_id="agent_abc123",
    api_key="lsk_admin_...",  # From dashboard
    server_url="https://lockstock-api-i9kp.onrender.com",
    path_tasks={
        "/v1/chat/completions": "chatcompletion",
        "/v1/models": "network",
        "/health": None,  # Excluded from stamping
    },
)
```

### 4. Remove Guard Daemon

If you were running the Guard daemon, you can now remove it:

```bash
# Stop the daemon
lockstock-guard stop

# Optional: Remove daemon package
pip uninstall lockstock-guard
```

### 5. Update Environment Variables

**Before:**
```bash
LOCKSTOCK_SOCKET=/var/run/lockstock-guard/guard.sock
LOCKSTOCK_SERVER_URL=https://lockstock-api-i9kp.onrender.com
LOCKSTOCK_AGENT_ID=agent_abc123
```

**After:**
```bash
LOCKSTOCK_SERVER_URL=https://lockstock-api-i9kp.onrender.com
LOCKSTOCK_AGENT_ID=agent_abc123
LOCKSTOCK_API_KEY=lsk_admin_...
```

### 6. Configure Path Tasks

The thin middleware requires explicit path-to-task mapping:

```python
path_tasks = {
    # Stamp these endpoints with their task types
    "/v1/chat/completions": "chatcompletion",
    "/v1/embeddings": "embedding",
    "/v1/models": "network",

    # Exclude these from stamping (use None)
    "/health": None,
    "/metrics": None,
    "/readiness": None,
}
```

### 7. Optional: Configure Response Stamping

For request-response pairing in the audit trail:

```python
app.add_middleware(
    LockStockThinMiddleware,
    agent_id="agent_abc123",
    api_key="lsk_admin_...",
    path_tasks={"/v1/chat/completions": "chatcompletion"},
    response_tasks={"chatcompletion": "chatcompletion_response"},
)
```

Response stamps are fire-and-forget (non-blocking).

### 8. Optional: Configure Blocking Mode

By default, the thin middleware proceeds with unstamped requests on failure.
To enforce stamping (return 503 on rejection):

```python
app.add_middleware(
    LockStockThinMiddleware,
    agent_id="agent_abc123",
    api_key="lsk_admin_...",
    path_tasks={"/v1/chat/completions": "chatcompletion"},
    block_on_rejection=True,  # Return 503 if stamp fails
)
```

## Response Headers

Both v1 and v2 inject `X-LockStock-*` headers into responses:

| Header | Description |
|--------|-------------|
| `X-LockStock-Status` | `accepted`, `skipped`, or `rejected` |
| `X-LockStock-Seq` | Sequence number (if accepted) |
| `X-LockStock-Hash` | State hash (if accepted) |
| `X-LockStock-Trace` | Trace ID for debugging |
| `X-LockStock-Reason` | Reason (if skipped/rejected) |

## Troubleshooting

### "Connection error" in logs

Check that `server_url` is reachable:

```bash
curl -I https://lockstock-api-i9kp.onrender.com/health
```

### "401 Unauthorized" from /v1/stamp

Your API key is invalid or expired. Generate a new one from the dashboard.

### "403 Task not allowed"

The task type isn't in your agent's `allowed_tasks`. Update the agent in the dashboard.

### "409 Conflict" retries exhausted

High concurrency is causing chain conflicts. The middleware retries 3 times with backoff, but if you're seeing this repeatedly, consider:
- Reducing concurrent requests
- Batching requests
- Contacting support for rate limit increase

## API Changes

### Removed in v2

- `guard_socket` parameter (no daemon)
- `LockStockMiddleware.sync_chain()` (server is authoritative)
- Local chain state tracking (server handles this)

### Added in v2

- `api_key` parameter (required)
- `path_tasks` parameter (explicit task mapping)
- `response_tasks` parameter (optional response stamping)
- `block_on_rejection` parameter (enforcement mode)
- `timeout` parameter (HTTP timeout)
- `max_retries` parameter (409 retry count)

## Questions?

- Documentation: https://d3cipher.ai/docs
- Support: support@d3cipher.ai
- Dashboard: https://lockstock-api-i9kp.onrender.com/dashboard
