# Agent Pharmacy API (P0 dogfood stubs)

Status: **dogfood** · `$0` · no Lightning · no public domain.

Machine-readable products live under `/sku/`. This folder documents the intended
HTTP surface and ships local Python stubs you can run from the CLI.

## Intended endpoints

| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/.well-known/agent-pharmacy.json` | Discovery (brand, api_base, skus, payment status) |
| `GET` | `/sku/index.json` | Catalog index for agents |
| `GET` | `/sku/{id}.json` | Full SKU object (bench, price, artifact hash) |
| `GET` | `/artifacts/{id}.zip` | Pack zip (dogfood: open download) |
| `POST` | `/api/invoice` | Create order + invoice (stub: `price_sats: 0`, `payment_required: false`) |
| `GET` | `/api/unlock/{order_id}` | Return signed unlock + artifact URL (stub: HMAC token) |
| `POST` | `/api/unlock/verify` | Verify an unlock token (optional; stub via CLI) |

### Buy flow (production sketch)

```
1. GET  /sku/{id}          → description + bench + price
2. POST /api/invoice       → Lightning invoice or on-chain address + order_id + expiry
3. Pay  (within human allowance)
4. GET  /api/unlock/{order_id} → signed zip URL + hash + license
5. Install skill · optional version-pin updates
```

**Hard rule:** A human sets the spend ceiling. The agent cannot raise it.

### Dogfood behavior

- `payment_required: false`
- `price_sats: 0` / `dogfood_price_sats: 0`
- Unlock is **immediate**; download `/artifacts/{sku}.zip` without paying
- HMAC tokens are for version-pin demos only (secret: env `PHARMACY_HMAC_SECRET`, default `dogfood-secret`)

## Stubs (run locally)

### `unlock_stub.py`

HMAC-SHA256 unlock token create/verify (stdlib only).

```bash
# demo (create + verify + negative checks)
python3 unlock_stub.py --demo

# create
python3 unlock_stub.py --create --order-id dogfood-001 --sku chill-v1 --ttl 3600

# verify
python3 unlock_stub.py --verify '<token>'
```

Functions:

- `create_unlock(order_id, sku, exp) -> str`
- `verify(token, *, now=None) -> dict`

### `invoice_stub.py`

Returns fake invoice JSON with immediate unlock instructions.

```bash
python3 invoice_stub.py --sku chill-v1
python3 invoice_stub.py --sku anti-slop-v1 --order-id dogfood-order-001
```

## Serving static site

From `site/`:

```bash
python3 -m http.server 8080
```

Then open `http://127.0.0.1:8080/` — SKUs and artifacts are static files.
HTTP `POST /api/invoice` is **not** wired yet; use the CLI stubs until a real
handler is added (P1+ with domain + Lightning).

## P1 blockers

- Domain purchase (Bob spend)
- Lightning node / LNbits / similar micropay
- Real `POST /api/invoice` + paid unlock gate
