# Phase status

Tracks tasks from BLUEPRINT.md §11–§12.

## Eval harness (BLUEPRINT.md §13 — Phase 1 essential, completed late)

| Feature | Status |
|---|---|
| 6-case eval set with hand-validated canonical summaries | ✅ |
| `interpret/scripts/eval.py` runner with per-metric floors | ✅ |
| Documented cron/timer wiring in DEPLOY.md | ✅ |

## Phase 5

| Feature | Status |
|---|---|
| Rare-pattern modules (curated bundles) | ✅ |
| Module browser + detail (PWA) | ✅ |
| Concept-driven rhythm-focus filter | ✅ (uses Phase 3 concept filter) |
| Inverse-quiz ("diagnose from clues") | ⊝ (deferred) |

## Phase 4

| Feature | Status |
|---|---|
| DB migration: signal_storage_key + measurements_verified | ✅ |
| Python verifier scaffolding (lazy load, threshold compare) | ✅ |
| Interpret service `/v1/interpret` accepts signal_url | ✅ |
| API + worker + ingest CLI carry signal_url through | ✅ |
| ECG-FM loader + forward-pass implementation | ⏳ (operator step; weights install + focused PR to wire loader) |

## Phase 3

| Feature | Status |
|---|---|
| EWMA mastery updater after each attempt | ✅ |
| SM-2-style next_review_at scheduling | ✅ |
| Review-queue endpoint + UI | ✅ |
| Concept deep-dive (Practice) route | ✅ |
| Splash CTA when concepts are due | ✅ |
| ECG-FM numerical verifier | ⏳ (Phase 4) |

## Phase 2

| Feature | Status |
|---|---|
| Settings UI (training_level + display_name) | ✅ |
| Concept filter on case list | ✅ |
| PHI scanner on uploads (tesseract.js + regex) | ✅ |
| Upload UI + de-id attestation | ✅ |
| Async interpret worker (in-process poll) | ✅ |
| Sign in with Apple | ⊝ (skipped — parent /login already gates) |
| Curator review UI | ⏳ (Phase 3 candidate) |

## Phase 1

| # | Task | Status |
|---|---|---|
| 1.1 | Monorepo scaffold | ✅ |
| 1.2 | Shared contracts package | ✅ |
| 1.3 | Database migrations & seed | ✅ |
| 1.4 | API skeleton + auth | ✅ |
| 1.5 | Interpretation service skeleton | ✅ |
| 1.6 | Tutor service skeleton | ✅ |
| 1.7 | Case ingest pipeline | ✅ |
| 1.8 | PWA shell | ✅ |
| 1.9 | EKG viewer component | ✅ |
| 1.10 | Learner input form | ✅ |
| 1.11 | Submit flow + tutor response | ✅ |
| 1.12 | Deployment (scripts written; user runs on droplet) | ✅ |

## Adaptations from the blueprint

The blueprint assumes a standalone `ekg-tutor/` repo with pnpm workspaces and
Docker Compose on AWS Lightsail. Living inside adampowell.pro and the existing
DigitalOcean droplet required:

- **Path layout.** Code lives at `apps/ekg-tutor/` (one cohesive subsystem)
  rather than the blueprint's `apps/web/`, `apps/api/`, `apps/tutor/`,
  `services/interpret/` at a repo root. The internal layout mirrors the
  blueprint otherwise.
- **Auth.** No JWT. The parent site's `/login` + `auth.service` gate the URL;
  ekg-tutor-api resolves the username by calling
  `http://127.0.0.1:3003/api/auth/check` with the forwarded cookie on each
  request. A lightweight `users` table is keyed by parent-session username.
- **Database.** Postgres 16 native, sharing the existing droplet instance
  that already serves `sharedtodo`. Separate `ekg_tutor` database + role.
  pgvector installed at provisioning time for Phase 2+ semantic search.
- **Runtime.** systemd, not Docker Compose. Three units:
  `ekg-tutor-api.service` (3110), `ekg-tutor-tutor.service` (3111),
  `ekg-tutor-interpret.service` (3112). All bound to 127.0.0.1.
- **Storage.** Local filesystem at `/var/lib/ekg-tutor/uploads/` instead of
  S3 / pre-signed URLs. Storage interface stays clean so DigitalOcean Spaces
  can be swapped in for Phase 2 if usage scales.
- **Secrets.** `/root/secrets.env` (existing convention) with an
  `EnvironmentFile=` line in each systemd unit. No `.env` files committed.

## Phase 1 decisions resolved

From BLUEPRINT.md §15:

- **Product name:** EKG Tutor (placeholder kept).
- **LLM provider:** Claude Sonnet 4.6 only, no abstraction layer.
- **Strip rendering:** PhysioNet ecg-image-kit applied to PTB-XL records.
- **Clinical review:** self-review (CRNA) before launch; 20 seed cases.
- **Device scope:** iPhone 16 Pro Max only.
