# system/ — Health, Version, Heartbeats

See @../../CLAUDE.md for project-wide patterns.

## What This Is
Infrastructure endpoints for health checks, version info, and loop heartbeat management. REST-only (no tools.py, no client.py).

## Endpoints
- `GET /api/health` — `{"status": "ok", "auth_required": bool}` (no auth required)
- `GET /api/system-info` — `{"version": str}` (version from importlib.metadata, "dev" fallback)
- `PUT /api/loops/{loop_id}` — upsert heartbeat (INSERT ... ON CONFLICT DO UPDATE preserving original started_at via COALESCE)
- `DELETE /api/loops/{loop_id}` — remove heartbeat
- `GET /api/loops?project_id=` — list active loops (heartbeat within 90 seconds)

## Gotchas
- Health check is always accessible — no API key required
- Heartbeat TTL is 90 seconds — loops write every 30s, so missing 3 beats = considered dead
- Upsert uses `COALESCE((SELECT started_at FROM loop_heartbeats WHERE id = ?), CURRENT_TIMESTAMP)` to preserve original start time on re-insert
- Loop.py writes heartbeats from a daemon thread (not the main agent process)
