The question my own prototype couldn't survive
I was clicking through an early build of TrialProof late one night, playing the part of the person who actually gets asked the hard questions: the regulatory-affairs lead who sits next to the VP of Clinical Operations when a sponsor reviews how patients were screened. So I asked my own screen the question she would ask. "Show me why you excluded this patient, and prove I would get the same answer if I ran it again next week." My prototype had a verdict. It did not have an answer. That gap is the reason the product exists.
Patient-matching AI reads a clinical note as text, so it confuses words that look alike but mean different things in medicine. The canonical failure is a Phase III anticoagulant trial that excludes "cardiac catheterization" while a patient's note says "central venous catheter placement." A similarity matcher sees two cardiovascular catheter procedures, scores them close, and can throw away a patient who was eligible. Published evaluations confirm models make this exact error (Fierce Biotech, 2025). And the numbers around getting enrollment wrong are not abstract: roughly $800K/day in lost prescription sales per day of enrollment delay (Tufts CSDD Impact Report, 2024), $840K/day in oncology and $1.4M/day in cardiovascular (Tufts CSDD), with 80% of trials missing their enrollment timelines (industry consensus, 2025) against protocols whose procedure counts are up 139% since 2005 (IQVIA, 2026). None of that spend buys you an answer to the regulatory-affairs lead's question if all your model produced was a score.
The day a 0.437 taught me what a score leaves out
What changed how I think about this was watching two systems agree and realizing only one of them had said anything. I loaded a synthetic post-ICU patient, P-074, whose note reads "ICU course notable for central venous catheter placement for IV medication access," against a synthetic anticoagulant protocol (ANTI-3) that prohibits prior cardiac catheterization. My fair lexical baseline (an honest TF-IDF cosine matcher, its threshold cross-validated to its own advantage at t = 0.6932) scored the two catheter phrases at 0.437 and returned ELIGIBLE. Correct verdict. And completely mute about why. TrialProof returned ELIGIBLE too, but with a three-step trace: the criterion is a prohibition on Cardiac catheterization (41976001); is Central venous catheterization (392230005) an is-a descendant of it? False, different branch of the SNOMED hierarchy; therefore no verified fact is subsumed by the prohibited concept, so the patient is not excluded. Both of those concept IDs are real, and anyone can check them on a public SNOMED browser. That was the moment it clicked for me. A number cannot be filed, audited, or argued with. A trace can.
The same verdict from both systems (the prohibition is "Met," so the patient stays ELIGIBLE). TrialProof names the two SCTIDs and the is-a check that decided it; the baseline line at the bottom is a similarity score with "no provenance, not reproducible."
The number I stopped putting first
I used to lead with the accuracy figure, and I have mostly stopped. On the demo's fixed 13-case labeled gold set, TrialProof scores 100% against the fair baseline's 53.8%. That is the number everyone wants on a slide. It is not the number a Head of Feasibility loses sleep over. The one that matters sits right underneath it: eligible patients lost, 0 for TrialProof and 3 for the baseline. Three candidates the vector matcher would have discarded.
One of them is almost embarrassingly simple. The note says "No evidence of diabetes." The trial excludes a diagnosis of diabetes mellitus. The baseline matches the token "diabetes" against the criterion at similarity 1.0 and excludes the patient, because a similarity score has no way to represent the word "no." TrialProof's verifier reads the same span, sees the negation, and strips the fact before it can reach the decision, so the patient stays eligible. At $1,200 per screen failure (Antidote.me, 2025) the accounting is dull. The human version is that a matcher confidently threw away someone who qualified, and did it at maximum confidence.
The negation save. On "No evidence of diabetes" the baseline excludes at similarity 1.0; TrialProof's verifier strips the negated mention and keeps the patient eligible.
What I decided a receipt actually has to survive
I got stubborn about one thing: a receipt is worthless if it changes when you re-run it. So the eligibility verdict in TrialProof is not something the model votes on. The provider-swappable LLM is advisory only. It reads the note and proposes facts with the exact span it read them from, an adversarial verifier throws out what the note does not support (a negated mention, a family-history attribution, a hallucinated drug), and then plain deterministic Python over the ontology and the dates computes the verdict. The model cannot overrule that gate. Which is what makes the next part possible: re-running the whole 13-case gold set produces byte-identical verdicts and traces, 13 out of 13. Same chart, same answer, every time.
That reproducibility is what I now open with when I show it, because it is the answer to the question my prototype could not survive. Every decision exports as a CDISC SDTM IE record in JSON and CSV, one row per patient and criterion, carrying the verdict, the SCTIDs, the deontic operation, and for note-derived facts the verbatim span it was read from. 100% of TrialProof's decisions carry that trace; the baseline's carry 0%. It is a format a regulatory-affairs lead already knows how to file, which turned out to matter more than I expected, given the FDA's January 2026 Clinical Decision Support guidance is the frame for exactly this kind of human-in-the-loop matching aid.
The 13-case labeled gold set. The tile I care about is the third one, eligible patients lost: 0 versus 3. The banner confirms byte-identical re-runs, and the export writes a CDISC SDTM IE record.
None of this makes TrialProof a Tempus, an IQVIA, or a Deep 6. It is not a data network or a cloud matching platform. It is the deterministic reasoning and provenance layer those platforms leave out, and you can run the whole thing yourself at veriprajna.com/demos/clinical-trial-recruitment-ai. Every patient and protocol in it is synthetic. The SCTIDs and the logic are not.
The question I keep coming back to is the one I could not answer that night. If your patient-matching system excluded someone tomorrow, could it hand you the concept ID and the rule that decided it, and would it give you the same answer next week? If the honest reply is a similarity score, it is worth asking what you would put in front of the person who has to file it.