← Home · Deep health

# Coordinator runbook (NFR-6)

**Audience:** on-site coordinator running a delivery week without an engineer.  
**Companion:** `docs/ops/backup-restore.md`, `docs/lms-v1-technical-spec.md` v3.1.

## Golden rules

1. Path `/c/<course_instance_id>/…` is routing only — every action still goes through authz.
2. Prefer **Teaching Week** (`/c/<id>/week`) over ad-hoc SQL. `/board` redirects to `/week`.
3. Jobs are idempotent — safe to re-enqueue; check **DLQ** on `/week` ops footer.
4. Human WhatsApp/Signal paste for claims first (FR-W1). Business API is optional and dual-gated.
5. Synthetic rosters only in dev (NFR-10).

## Day-0 checklist

- [ ] Postgres + object storage up; `GET /api/health?deep=1` → `ok`
- [ ] Seed or import roster; copy claim paste packs once (`/c/<id>/whatsapp`, Business off)
- [ ] Pin ContentRelease; unlock Day-1 modules on `/week`
- [ ] Unlock MOI Before survey if required
- [ ] Confirm join brief EN/AR

## During delivery

| Task | Where |
|------|--------|
| Unlock schedule modules | `/c/<id>/week` → Module map |
| Surveys / feedback chase + exports | `/c/<id>/week` → Surveys & feedback (EC completion only; IPP desk; attributed steward-only) |
| Progress desk | `/c/<id>/week` → Progress (manifest-driven) |
| Open/close hosted apps (A1) | `/c/<id>/week` classroom ops (or `/c/<id>/apps`) |
| Submission inbox review | `/c/<id>/inbox` (also linked from `/week`; requires `inbox.review` — participants see only their own files; IPP/steward cannot bypass via `media.grant`) |
| Attendance / completion / certs | `/c/<id>/week` classroom / logistics |
| Re-pin content (preview → accept → commit) | `/c/<id>/fleet` |
| Lifecycle close / archive | `/c/<id>/week` or `/c/<id>/fleet` |
| WhatsApp paste / optional Business | `/c/<id>/whatsapp` |

## Offline / Wi‑Fi notes (NFR-3)

- Teaching decks: after authorized first fetch, bounded private cache is OK.
- Hosted Class A1 apps: presenter single-machine fallback — share screen if classroom Wi‑Fi dies.
- Claim redeem and surveys need network; print sealed claim slips as backup.

## Jobs worker

```bash
npm run jobs:work
# or once:
npm run jobs:work -- --once
```

Teaching Week / jobs API can also enqueue + `run_next` for demo jobs. Production should run a dedicated worker.

Wave 2 exit evidence (synthetic week / paste dry-run): `docs/ops/w2-readiness-exit.md`.

## Retention (NFR-13)

- Clock starts when instance enters `archived` or `cancelled` (`retention_started_at`).
- Default **90 days** (`RETENTION_DAYS`).
- Jobs: `export.expire`, `retention.instance_sweep` (`/c/<id>/fleet` retention buttons).
- Certificate ledger is **not** purged.

## When to escalate

- Deep health degraded (Postgres or S3)
- DLQ growing with unknown job types
- Cross-tenant suspicion (Sev-1 — stop and escalate)
- Live re-pin accept token mismatch after preview drift

## Staff credentials (synthetic seed only)

`onsite@example.test` / `onsite-dev` — never use in production IdP.