# Deployment Procedures

## Pre-Deployment Checklist

- [ ] All CI tests pass (lint, unit, E2E)
- [ ] Docker images built for aarch64 (Jetson)
- [ ] TRT engines exported on matching JetPack version
- [ ] Config file updated if needed
- [ ] USB drive prepared with: images, engines, config, update.sh

## Standard Deployment

```
1. Connect USB to Jetson
2. Run: sudo /mnt/usb/update.sh
   - Stops running containers
   - docker load < semantic-detection-{version}.tar
   - docker load < vlm-service-{version}.tar (if VLM update)
   - Copies config + engines to /models/ and /etc/semantic-detection/
   - Restarts containers
3. Wait 60s for cold start
4. Verify: curl http://localhost:8080/api/v1/health → 200 OK
5. Remove USB
```

## Model-Only Update

```
1. Stop semantic-detection container
2. Copy new .engine file to /models/
3. Update config.yaml engine path if filename changed
4. Restart container
5. Verify health
```

## Health Checks

| Check | Method | Expected | Timeout |
|-------|--------|----------|---------|
| Service alive | GET /api/v1/health | 200 OK | 5s |
| Tier 1 loaded | health response: tier1_ready=true | true | 30s |
| Gimbal connected | health response: gimbal_alive=true | true | 10s |
| First detection | POST test frame | Non-empty result | 60s |

## Recovery

If deployment fails or system is unresponsive:
1. Try restarting containers: `docker compose restart`
2. If still failing: re-deploy from previous known-good USB package
3. Last resort: re-flash Jetson with SDK Manager + deploy from scratch (~30 min)
