Intervention ROI — the return-on-action engine (sibling of stress curves)
Status: v0 BUILT 2026-07-15 as "Levers" (task 7cff4348). Named Levers — an
intervention is a lever on a level. Falls straight out of the Downstream
lineage. v0 = track a level (name + scale) → log readings → log interventions with an
optional predicted Δ → a per-intervention ROI list scoring actual vs. predicted.
Backend levers-core.ts (pure, tested 8/8) + levers.ts + /api/levers, migration 488
(levers_levels / levers_readings / levers_interventions), page /dashboard/levers.
See INDEX.md → Levers. The v0 wedge below (prediction-vs-reality) is what shipped, plus
summarizeLevers — repeated pulls of a lever roll into an average effect, ranked
("What moves <level>"), which is the per-user X-vs-Z comparison (one before/after is
noise; the mean is the return). Still ahead: cross-window counterfactuals (X vs Z vs
nothing), between-people/normative dose–response, wearable/lab import.
The idea in one paragraph
You're tracking the level of something — energy, satisfaction, hunger, mood, pain, sleep quality, weight, a lab value like potassium. You take interventions — an action X (a walk, a supplement, a nap, a hard conversation, eating, meditating). The question ROI answers: how much does action X change the level of Y — versus not taking X, versus taking a different action Z? And two layers on top: your prediction vs. what actually happened, and how your response differs from other people's.
Why it belongs in this lineage
Downstream (stress curves) models the cost of inaction — how a thing's cost/ stress grows the longer you leave it alone (the do-nothing curve). ROI is the exact complement: the return on action — how a tracked level moves because you did something. Same substrate ("levels over time"), opposite operator:
| Downstream | Intervention ROI | |
|---|---|---|
| Tracks | cost/stress of a deferred thing | the level of some quantity |
| Driver | time (inaction) | interventions (action) |
| Core question | "what flows downstream if I wait?" | "what do I get back if I act?" |
| Calibration | "how bad was it really?" (resolve tap) | "did the action do what I predicted?" |
| Open science | shape of procrastination cost | dose–response between people |
Together they're a fuller model of levels over time and what moves them.
We've already built most of the substrate
The ultradian rhythm engine is, quietly, the first instance of exactly this shape:
- A tracked level — energy (
downstream_energy_taps). - Interventions — completed focus sessions already register as a signal that moves
the estimate (
focusEnergyTaps). - Prediction vs. reality — Downstream's resolve-time "easier / as expected / worse" tap is the same predicted-vs-actual pattern.
- Between-people — the anonymized normative "shape of the day" (
aggregateEnergyCurve) is the dose–response-between-people overlay, already shipped.
ROI is the generalization: let the user track any level and log any intervention, then reuse this exact machinery to estimate the effect.
The comparison structure (the hard, honest part)
"How much does X change Y" is causal inference from n-of-1 observational data, and that's genuinely hard — confounders, regression to the mean, placebo, and the fact that you can't take and not-take X at the same moment. The product must not overclaim.
Three honest framings, weakest → strongest:
- Before/after deltas — the level's change in a window after X vs. its own baseline. Cheap, but confounded (correlation, not cause). Label it as such.
- X vs. not-X vs. Z — compare the post-X window against matched windows where you did nothing / did Z. Better, needs enough logged days to have counterfactual windows.
- Prediction vs. reality — you forecast the effect ("this nap will raise my energy 2 points"), then we measure the actual delta. This sidesteps the causation claim entirely — it's your hypothesis, scored — and doubles as the calibration signal. This is the wedge: honest, motivating, and it makes the user a co-investigator.
Between-people rides the citizen-science infra: "for most people X moves Y by ~Δ; for you it's different" — the same personal-vs-normative overlay we already ship for energy.
Possible v0 wedge
Pick one level + a short intervention list + the prediction loop, reusing the rhythm machinery:
- Track a level — a generic
tracked_level(name, unit, scale) with time-stamped readings (self-report first; wearable/lab import later). Energy is the seed instance. - Log interventions — a time-stamped
intervention(name; optional predicted effect). - The response view — for a level, overlay its readings with intervention markers; show the before→after delta per intervention with an honest "correlation, not proof" caveat, and predicted vs. actual when a prediction was made.
- Normative later — once there's data, the between-people dose–response overlay.
Everything above generalizes structures that already exist (downstream_energy_taps →
level_readings; focusEnergyTaps/sessions → interventions; aggregateEnergyCurve →
the response aggregation).
Open questions
- Product boundary — a Downstream mode, or a sibling app? (Downstream = cost of inaction; ROI = return on action; they're two operators on one "levels" core.)
- Naming — Levers (an intervention is a lever on a level) reads well.
- Domains + GTM — quantified-self / health is the obvious home; ties to DreamPro (aspiration) and any lab/wearable data. Potassium-style lab values suggest a health-tracking angle with real stakes (and real overclaiming risk — counsel/clinical bright lines if it ever touches medical decisions).
- Rigor vs. approachability — how much causal honesty to surface without killing the motivating "I did X and Y went up" loop. The prediction-vs-reality framing is the release valve.
Related
- DOWNSTREAM.md — the cost-of-inaction sibling; shares the "levels over time" substrate and the calibration/open-science patterns.
- DOWNSTREAM_AUDIO_IDEAS.md §3 — the rhythm engine, the first built instance of level + interventions + normative.