There are two ways to model a body, and consumer health apps overwhelmingly do the first one. The first one - the kind that looks at your wearable data and your survey responses and surfaces population trends - is called epidemiological, and it is a perfectly fine tool when you're studying populations. The thing is, you're not a population. You're one body, on a specific morning, with a specific set of compounds already in circulation, and the question you're actually trying to answer is mechanistic: "If I add this thing, what happens to my body, specifically?"
The other kind of model - the kind that answers that question - has existed for forty years. The FDA calls it PBPK, Physiologically-Based Pharmacokinetic modeling, and pharmaceutical companies use it before every Phase I trial to extrapolate from healthy 30-year-old males to pregnant patients with kidney disease. The math isn't new, and Protokol Lab doesn't pretend to reinvent it — the engine is inspired by the same class of mechanistic models used in pharmacometrics and PBPK research, without claiming the regulatory validation those submissions carry.
What's new is that real-time ODE integration, that AI-driven research aggregation makes a 1,200-compound library feasible, and that there's a growing class of individuals - the self-clinicians - who actually want more personalized health data in their hands.
So I built it. This is a letter explaining how.
A word on why. I spent years trying to reason about my own body - stacking compounds, reading studies, watching bloodwork move - and never had a tool that could tell me what a change would actually do before I gave it months of my life. The math to do that has existed for forty years; it just never left pharma. That gap is the reason this exists.
A note before we begin: This document is long because I think the people I most want to use Protokol Lab will want to read the long version. The one-paragraph version is: it's an ODE engine and a library of pkpd data with values that are cited at compile time, and we hire people to audit it in Phase 3. If that's enough, skip to the appendix. If you want to understand why each of those points are relevant and important keep reading.The philosophy
Statistical correlation is different than mechanistic simulation.
Levels, InsideTracker, Whoop, Oura - these are wonderful products. They look at your trends and surface statistical relationships. They tell you "people with your data tend to do X." That kind of inference is genuinely useful. It is also not the same job as what Protokol Lab does.
The lab decomposes every input down to its physical biology. When you add 100 mg of caffeine, the engine does not ask "what do users like you tend to feel?". It asks "how much caffeine reaches the plasma, how does it bind adenosine A1 and A2A receptors, how does that shift cortisol production, what happens to HRV, and what does that look like at 3 AM?" The first question is correlational. The second question is mechanistic. Mechanistic is harder. It is also the one most of you are actually asking when you open the app.
For the record: Levels and friends are good products doing good work. I'm pointing out that Protokol Lab takes a different approach - mechanistic modeling - and it's mostly been used in big pharma and FDA submissions - not consumer health apps.
A forecast, not an oracle.
Let me be precise about what this is for. The goal is not perfect prediction of your biology - no model of a living system gets that, and anyone who promises it is selling something. The goal is useful, directional reasoning: a defensible answer to "if I add this, which way does it move me, roughly how much, and how confident should I be?" A weather forecast isn't valuable because it's never wrong. It's valuable because it's far better than guessing. The lab is built to be exactly that - a way to reason about an intervention before you spend months living through it.
The architecture
One state vector. One integrator. The rest is declarations.
Every signal, every receptor, every internal pool, every drug currently in your blood - is one differential equation. The integrator is a Runge-Kutta 4 solver and the output state is flattened into a series of numeric values. At every timestep it asks:
It is literally one equation, vectorized, with the right-hand side composed from the pharmacology declarations of whichever compounds are active. The shape of any single signal - say, dopamine - is mean-reverting toward a setpoint μ(t), with a time constant τ, plus production, minus clearance, plus couplings from upstream signals. Each of those terms is its own cited number.
The pharmacokinetic side of the engine is what most "wellness simulators" don't do. Drug clearance is composed live from your biology - it is not a fixed half-life pulled from a textbook. The engine exposes 23 per-isoform enzyme-activity signals (every CYP, every UGT, the major phase-II pathways, the clinically relevant transporters), and each one carries a live multiplier built from your sex, age decline, pharmacogenetics, pregnancy state, inflammation, and any inhibitor or inducer currently in your stack. Hepatic clearance is the standard well-stirred formulation:
None of that math is invented here. It is implemented here. The contribution is not the equation; it is the engineering - composing it, in real time, in a browser, off a typed declaration of every drug. Adding a compound looks like this:
// Caffeine, 100 mg oral pill const caffeinePill: InterventionDef = { key: "caffeinePill", pharmacology: (p) => ({ molecule: { name: "Caffeine", molarMass: 194.19 }, pk: { model: "1-compartment", halfLifeMin: 300, bioavailability: 0.99 }, pd: [ { target: "Adenosine_A1", mechanism: "antagonist", Ki: 12000, ... }, { target: "Adenosine_A2a", mechanism: "antagonist", Ki: 2400, ... }, ] }) };
There is no special caffeine code path. That declaration is the entire caffeine model. The PK runs through the well-stirred formula. The PD runs through the Operational Model of Agonism. The downstream effects on cortisol, dopamine, sleep, HRV - those happen because those signals have couplings to those receptors, each one declared independently, each one cited.
Your physiology is the other half of the equation.
The same engine runs against a typed declaration of you. Sex, age, weight, lean mass, hepatic and renal function, hematocrit, plasma proteins, inflammation markers - every one is a live signal the right-hand side reads on every tick. Bloodwork from your last labs becomes the initial condition. Setpoints don't anchor to a textbook population mean; they anchor to yours.
Genetics are typed the same way. A CYP2D6 poor metabolizer doesn't trigger a special code path - the genotype enters the per-isoform activity composition, the activity multiplier drops, intrinsic clearance drops, and every substrate routed through that pathway slows down at the right rate. Same shape for CYP2C19, VKORC1, UGT1A1, and the rest of the clinically actionable variants.
Conditions are interventions on the physiology itself. Hypothyroidism, PCOS, T2D, chronic kidney disease, hepatic impairment, pregnancy - each is a cited bundle of setpoint shifts and signal couplings, structurally no different from a drug. Flip one on and the relevant signals re-equilibrate before any compound is dosed. Your subject definition looks like this:
// You, as the engine sees you const subject: SubjectDef = { sex: "M", age: 38, weightKg: 78, heightCm: 180, bloodwork: { hsCRP: 0.6, alt: 22, egfr: 102, hba1c: 5.1, ... }, genetics: { CYP2D6: "poor", CYP2C19: "rapid", VKORC1: "AA", ... }, conditions: ["hypothyroidism"], };
One engine, one state vector. Drugs, genes, conditions, and bloodwork are all declarations on the right-hand side - never special cases, never branches in the integrator. Personalization is not a feature layered on top; it is the shape of f(S, t, P).
Data integrity
This is the part you should be most skeptical of.
The library has 1,200+ compounds. Each compound has roughly 20–80 numeric parameters. The audit walker covers another 91 signals, 80+ drug agents, 10 conditions, and 10 interaction rules. That's tens of thousands of numbers, every one of which needs a citation. No human team is hand-entering that at consumer-app speed.
The hard part isn't the equations.
Modeling one drug well is hard - pharma spends years doing it. The harder problem, the one this project actually lives or dies on, is maintaining thousands of parameters, citations, interactions, and validation tests at once, and keeping every one of them honest as the library grows. That maintenance problem - not the math - is the engineering challenge we're solving.
So we use AI. That should give you pause - large language models hallucinate numbers all the time. They will confidently report a clearance rate of 36 mL/min for a drug whose actual clearance is 360 mL/min, and they will cite a paper that doesn't exist to back it up. The skepticism is correct. The answer comes in two parts: how we keep the numbers right, and how we keep any number from escaping accountability.
Data integrity at scale.
Every value runs a multi-stage pipeline - each stage adversarial to the last - before a human is ever asked to look at it:
We reference many sources. For each compound, condition, signal, receptor, and each other part of the system - we bring in the primary literature, regulatory filings, and pharmacology references.
Varied, and redundant data extraction. Several models extract independently. A third evaluation step compares them against the source data and the best is kept.
Text data is grounded with visual context. Several vision models extract simultaneously, and independently. Every number is anchored to its exact position on the page - so a value can be traced back to the spot it was read from.
Test validation. The consolidated values are compiled into the engine and run, then checked by independent agents against the tests written from the source literature.
Then, and only then, does any of it reach a person - a clinician, a pharmacometrician, a biochemist - to walk the surviving values back to the paper and sign off. Human review is the last gate on top of an already-adversarial pipeline, not the only thing standing between a hallucinated number and your screen.
From those same citations, verification tests are written and run against the engine's output. The test corpus grows with every new compound and every new signal: today it contains 1,200+ scenarios, each with unique subject data, that run automatically on every deployment. The test is locked to the literature, not to the engine's current output, and if the engine cannot satisfy a test, the failure surfaces in the queue and a human adjudicates.
Violations can decrease, but never grow.
Behind the test corpus sits a human review pipeline. Qualified reviewers — pharmacometricians, clinical pharmacologists, biochemists - walk each extracted value back to its source paper and sign off. Phase 3 hires that team specifically to close the remaining gap.
The other half of the answer is that citation provenance is structural, not editorial. Every numeric coefficient in the engine that carries biological meaning is wrapped, at compile time, with a citation. There are no bare numbers in any path that requires literature.
// This is what every PK/PD constant looks like export const CYP2D6_POOR_ACTIVITY = cited(0.22, [ { ref: "cpic-cyp2d6-guideline-2020", supports: "PM → ~4.5× AUC for atomoxetine substrates", quote: "Poor metabolizers achieved approximately five-fold higher exposure", }, ]); // `ref` is typechecked against the registry. // Typos fail the build, not the simulation.
The library itself lives in an append-only versioned database - every value carries a timestamp and an author, and can be walked back through every revision it has ever had.
As the team and the (incoming, Phase 3) auditors pay down evidence debt, the ratchet tightens automatically. This is, deliberately, a debt-paydown model with strong gates to prevent regression.
Three classes of evidence.
Not every number in the engine is backed equally, and the output never pretends otherwise. Every effect is tagged with one of three evidence classes, and that tag travels with the prediction.
Direct human evidence. A controlled human study measured this effect, at roughly this magnitude, in people. Highest confidence.
Mechanistic inference. The receptor-level mechanism is established in humans and the downstream effect follows from it - but that specific endpoint wasn't measured directly. Medium confidence.
Exploratory hypothesis. Animal data, in-vitro work, or a plausible mechanism on thin human evidence. Shown, flagged, and de-rated - never presented as settled.
So when the lab surfaces a number, you always know whether you're looking at a measurement or an extrapolation.
What would convince me I'm wrong
The ways this model can fail.
A model of human physiology can fail in specific, nameable ways. Here are the ones I actually worry about - and what we do about each.
Missing mechanisms. A real pathway simply isn't in the engine yet, so an effect goes unmodeled. Mitigation: the library is append-only and grows with every audited compound; a missing mechanism is a gap to fill, never a wrong number asserted with confidence.
Incorrect literature extraction. The AI pulls a value the source doesn't support. Mitigation: every value is wrapped with its citation at compile time, a test is written from that same source, and a qualified human walks it back to the paper before it ships.
Unmodeled interactions. Two compounds interact in a way no single declaration captures. Mitigation: the harm engine encodes interaction rules explicitly and refuses stacks it can't reason about, rather than silently averaging them.
Sparse evidence. The human literature is thin or conflicting. Mitigation: the effect is tagged exploratory and de-rated, and the engine declines to overstate confidence rather than papering over the gap.
Population-to-individual translation error. A parameter is right for a population but wrong for you. Mitigation: your bloodwork, genetics, and conditions enter as the initial condition, so the model anchors to your physiology - but this is the failure mode I trust least, and it's exactly where your own data and a clinician matter most.
Roadmap & phase
What we've shipped. What we're shipping. What we haven't yet.
Phase 1 is complete. The architecture is built. The ODE engine runs. The citation gate is wired up. The AI-TDD pipeline has been producing validated definitions for months.
Phase 2 - which is right now - is closed beta and computational proof-of-concept. The system works mechanically. The math is right. The library is in active review, and self-clinicians are running real scenarios against the engine.
Phase 3 is funded by founding-member revenue. The next hires are pharmacometricians, a clinical pharmacologist, and a PhD biochemist whose only job is to verify the AI's extraction line-by-line against the original citation. They review every value and sign off on it. The architecture has been engineered to make the audit straight forward and traceable. Every value is already cited, already traceable, already in the queue.
Beyond the disclaimer, the engine ships with a library of safety monitors that run on every simulation. Input monitors check the stack itself — known contraindications, accidental doubling, dangerous synergies, cumulative load on a single clearance pathway. Output monitors watch the trajectory — rates of change outside physiologic bounds, signals trending into dangerous territory, compounding effects that look fine in isolation and harmful in sequence.
If you're pregnant, breastfeeding, under 18, or stacking compounds with thin human literature, the engine flags it and refuses to overstate confidence. If you're making a decision that meaningfully affects a clinical condition, work with a clinician. The lab is built to support that conversation, not replace it.
If you use the lab and something looks wrong, tell me. If a citation doesn't match the value it's wrapped around, tell me. If a prediction diverges from what your bloodwork actually does six weeks later, tell me. The model gets better the more it's challenged by people who know more than I do, and I would rather hear it from you than ship it wrong.
I didn't build this to predict your future. I built it because I wanted a better way to reason about my own biology - to see, before I committed to a protocol, which way a change would push me and how sure I could be. That's the whole promise. It's one I can stand behind today, in five years, and for as long as the library keeps getting better. If it's a problem you have too, the email below is real and I read it myself.