100% offline No image upload WASM / WebGPU Physician-in-the-loop v1 detector: gate not met

FertiVision Local

An open research prototype for andrology & embryology image analysis. Sperm and follicle measurements are computed inside the browser via ONNX Runtime Web. The localhost server only ever sees structured JSON. Every deterministic verdict cites its ruleset. Every measurement carries a physician sign-off.

┌──────────────────────────────┐        ┌──────────────────────────────┐
│  Browser (this site)         │        │  Local FastAPI  (your Mac)    │
│  ────────────────────────    │        │  ─────────────────────────    │
│  static/app.js  + detect.js  │  JSON  │  uvicorn server.app:app       │
│  • ONNX YOLO (WebGPU/WASM)   │ ─────► │  • Review queue: AI_DRAFT →   │
│  • deterministic JS fallback │ ◄───── │    UNDER_REVIEW → SIGNED_OFF  │
│  • SHA-256 in browser        │        │  • WHO 2021 / Gardner rules   │
│  • no fetch(image) ever │  • SQLite (fv_local.db)         │
│                              │        │  • PDF/JSON signed report     │
│  Images NEVER leave browser. │        │  • /narrate → Ollama LFM2.5   │
└──────────────────────────────┘        └──────────────────────────────┘
       127.0.0.1:9000 (static)                 127.0.0.1:8000 (uvicorn)

01Honest status, right now

Trained detector does NOT meet its own quality gate.
v1 measured mAP50 = 0.56 on participant-held-out frames. Acceptance gate: mAP50 ≥ 0.85. The browser therefore runs the deterministic fallback (Otsu + connected components) instead. This is by design — the system would rather be honest than ship a number without proof.
0.560
mAP50 (v1, held-out)
0.186
mAP50-95 (v1)
0.85
Acceptance gate (not met)

02What is actually working today

The infrastructure, the contracts, and the audit trail. The pieces you can independently verify on your own machine:

Deterministic blob counter

Pure JS, runs in the browser, polarity-agnostic (dark-on-bright and bright-on-dark). Unit-tested against synthetic ground truth in tests/test_detect_blobs.mjs — 6 cases including touching blobs, speckle rejection, and the area-gate threshold.

Deterministic rules engine

WHO 2021 5th-percentile cut points and Gardner blastocyst grading, covered by tests/test_rules.py — 35 boundary cases (OAT combinations, missing fields, C-grade blastocysts, exactly-at-limit).

Protocol contract enforcement

Every image analysis is gated by the study's "sheet contract" (chamber, field width, capture time). Calibration is fixed per study, so a series is always on the same scale. tests/test_protocol.py — 19 cases.

Quantified progression

Deterministic deltas, rates per day, ±15% flagging rule, divide-by-zero guards. tests/test_progression.py — 8 cases, including a 0-baseline guard.

03Reproducibility, not vibes

The next training run is bit-reproducible: SEED=0 pinned in train/train_sperm_yolo.py, torch.use_deterministic_algorithms enabled, participant holdout written to models/fold_split.json and committed. validation/validate.py computes a 95% bootstrap CI on mAP50 from per-frame scores — the v2 report will report 0.83 ± 0.04 instead of a single number.

Run commandWhat it proves
python3 tests/run_all.py 73 individual checks across 4 test files. Single CI command.
node validation/test_exif.mjs EXIF DateTimeOriginal parser round-trips a real JPEG header.
python3 validation/validate.py Honest gate verdict; refuses to enable a sub-gate model.
python3 validation/smoke_test.py Server end-to-end: HITL, protocol 422, calibration 409, feed timeline.

04How to run it on your machine

# 1. Python server (review queue + SQLite)
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn server.app:app --port 8000

# 2. Serve the browser app (any static server)
python3 -m http.server 9000 --directory static

# 3. Open http://localhost:9000
#    Images are processed in the browser. Nothing is uploaded.
#    Only structured JSON crosses 127.0.0.1.

05Provenance

ComponentArtifactProofLicense
Sperm detector (v1) models/sperm_yolov8n.onnx VISEM-Tracking (sperm-net, HF): 29,196 expert-annotated frames, participant-held-out Dataset CC BY 4.0; ultralytics AGPL-3.0 (train-time)
Sperm fallback static/detect.js Auditable algorithm; unit-tested; no ML claim our code
Rules engine server/rules.py WHO 2021 5th percentile; Gardner 1999; 35 boundary tests our code