Skip to content

ClinVal Validator

ClinVal Validator is built for one named user: the clinical-AI researcher who has trained a medical-imaging model and needs to know whether the reported AUC is real or an artifact of how the data was split.

Core trick

Checks patient-ID overlap between train and test splits, re-scores on a patient-disjoint subset, and reports AUC per scanner and site; Python computes all numbers.

Tags

Description

ClinVal Validator is built for one named user: the clinical-AI researcher who has trained a medical-imaging model and needs to know whether the reported AUC is real or an artifact of how the data was split. It ingests a model's predictions.csv (predictions plus patient/scanner/site metadata) and runs three deterministic checks: patient-level leakage (do patient IDs cross the train/test boundary?), a split-quality audit (re-score the same predictions on a patient-disjoint subset), and per-subgroup degradation (AUC by scanner and site). It then hands the resulting JSON to Claude, which writes either a GREEN/YELLOW/RED risk report or a journal-reviewer critique with a corrected, leakage-safe Methods paragraph the author can paste into their manuscript. One architectural rule is enforced end to end: Python computes every number; Claude only explains it. The validators run fully offline; the reporter is the only code that touches the network, and it may cite only figures already present in the JSON. It never computes a metric. What I found: on the real RSNA Screening Mammography cohort, a naive row-level random split — the default most people reach for — leaves 7,511 of 7,524 test patients (99.8%) also present in training, because each patient contributes four to five images. Nothing is wrong with RSNA. The mistake is splitting by image instead of by patient, and it is completely invisible unless someone counts. Why it matters: a leaked split doesn't merely inflate a number — it makes the number unanswerable, because it no longer measures what a clinical reader assumes it measures. The detectors are verified against six ground-truth-labeled synthetic scenarios, so the tool's own claims are checked, not asserted. MIT, no PHI, synthetic/public-schema data only.
vbabenko97/clinval-validator★ 00 forksPythonMITCreated Jul 8, 2026 · last push Oct 18, 2026

README excerpt

# ClinVal Validator

[![tests](https://github.com/vbabenko97/clinval-validator/actions/workflows/tests.yml/badge.svg)](https://github.com/vbabenko97/clinval-validator/actions/workflows/tests.yml)

ClinVal Validator reads a model's `predictions.csv` and reports two failure modes that make a clinical-AI performance claim unsafe: the same patient in both the train and test splits, and a subgroup whose AUC is lower than the rest of the table. Python computes the metrics, the flags, and the risk level. Claude is instructed to turn that JSON into a validation risk report and to cite only numbers present in it. Nothing in this repository checks the text Claude returns.

![ClinVal Validator on optimistic_site_shortcut: 990 leaked patients, leakage rate 98.8%, test-split AUC 0.988, patient-disjoint sample AUC 0.952, and a RED banner](docs/images/app-optimistic-site-shortcut.png)

*Offline view of the bundled synthetic `optimistic_site_shortcut` scenario. No API key was entered and no Claude report was requested. A test-split AUC of 0.988 would look publishable, but 990 patients are in both the train and test splits, so Python sets the risk level to RED. The fourth metric is the AUC of a patient sample drawn from all rows, including training rows. The −0.035 figure is that sample minus the test-split AUC; it does not measure inflation.*

The column names follow the Radiological Society of North America (RSNA) Screening Mammography Breast Cancer Detection dataset. This repository contai

Team