Coach DrépanoCoach DrépanoTreatments and questionnaires
Algorithm transparency

Treatments and questionnaires

Treatment regularity, questionnaire scores and rule-based reminders.

Each algorithm is described with what it reads, its steps, the values it uses (with their place in the code), what it shows and its limits.

Personal associationsPersonalized screening calendarStress load and resources ("balance")Short screeners: post-traumatic stress, ADHD, autismDepression and anxiety: PHQ-9, GAD-7 and Edinburgh scaleHydroxyurea follow-up test reminderHydroxyurea in the crisis riskHydroxyurea regularity (days covered)"Worth discussing with your team" signal (HbF or crises)How a day is classed as a "crisis" dayReminder the day before your crisis-prone weekdayPain check after a rescue painkiller"Default" doses and treatment regularity rateQuestions to ask your doctorQuestionnaire scores: self-efficacy, quality of life, perceived usefulnessMedicine stock and reorder reminderPerceived stress: PSS-10 scale and daily feelingSpaced "how are you?" and assumed valuesPrevention follow-up, vaccines and exam remindersInsights on your crises and regularity

← All algorithms

Personal associations

Trévor looks in your own data for cautious links between what you do or what surrounds you (sleep, weather, treatments, actions) and your pain, mood, form, fatigue or crises. A displayed link is not a cause.

Where you see it: Personal navigator dashboard, associations section.

What the algorithm reads

The calculation, step by step

Choose pairsOutcomes: pain, mood, form, fatigue, crisisExposures: everything else, except rescue analgesic and misseddosesPain and form are never crossed with each otherRank correlationFor each pair and each lag from 0 to 3 days: Spearman correlationbetween the exposure on day D − lag and the outcome on day DAt least 24 paired daysThe best lag is kept, its p-value multiplied by 4 (Bonferroni),capped at 1False discovery rateBenjamini-Hochberg across all tested pairsq ≤ 0.10 AND |rho| ≥ 0.25?yesnoAssociation kept, with 95%confidence intervalDroppedLimitStrongest first; at most 2 per outcome and 5 in totalWeekly scaleWeekly exposure means against questionnaire scores: at least 8weeks, |rho| ≥ 0.5, same q ≤ 0.10 control; at most 5
Flowchart: Personal associations

The values used

Name in the codeValueRoleWhere
LAGS(0, 1, 2, 3)Lags tested in dayssrc/trevor/navigator/findings.py:20
MIN_PAIRS24Minimum paired dayssrc/trevor/navigator/findings.py:21
MIN_ABS_RHO0.25Minimum |rho| (day)src/trevor/navigator/findings.py:22
MAX_Q0.10Maximum false discovery ratesrc/trevor/navigator/findings.py:23
MAX_FINDINGS5Total associationssrc/trevor/navigator/findings.py:24
MAX_PER_OUTCOME2Associations per outcomesrc/trevor/navigator/findings.py:25
MIN_WEEKS8Minimum weeks (weekly scale)src/trevor/navigator/findings.py:26
MIN_ABS_RHO_WEEKLY0.5Minimum |rho| (week)src/trevor/navigator/findings.py:27

What is shown

At most 5 daily then weekly associations (computed only from 21 days of data, navigator/api.py:11), each with lag, rho, n, p and q values, confidence interval.

A worked example

No numeric example was run (the calculation needs real series).

What this algorithm cannot do

Validation. Standard statistical method (Spearman, Bonferroni, Benjamini-Hochberg), thresholds set by the project team. No clinical validation or performance study in the repository.

Code : src/trevor/navigator/findings.py (daily_findings, weekly_findings, compute), src/trevor/navigator/stats.py, src/trevor/navigator/series.py (build)

Personalized screening calendar

Trévor reads a rules table (age, genotype, treatment) to tell you which monitoring exams recur at which pace, and when the next one is due based on the last date you enter. It organizes your follow-up, interprets no result and does not replace your care team.

Where you see it: "Screening calendar" screen (behind the prevention follow-up), for sickle-cell-type conditions; a child followed by a relative has their own calendar.

What the algorithm reads

The calculation, step by step

Sickle cell trait (AS)?yesnoNo calendarWe continueAgeWith the birth date: exact ageWith only the year: a range of two ages (n − 1 and n)With neither: unknown ageRule of each examThe exam's rules are read in order: the first matching genotype,treatment and age decidesUnknown age and age-dependent rule: "age needed"Minimum age not reached: "not yet"No rule: "not applicable"Rhythm "every nmonths"Due = last exam +n monthsNever entered:"never"Today ≥ due:"overdue"; 60 daysor fewer left:"soon"; otherwise"up to date"Rhythm "once"Done: "done";otherwise "never"Only "never" canbe remindedOther rhythms"not recommended","team decides","genotype needed":no reminderYour team has another paceIf you entered a different pace: the exam is no longer remindedReminderRemindable: applicable rule, overdue or near (60 days), notalready reminded for this due dateA "never entered" is reminded by the prevention plan, not by thislist
Flowchart: Personalized screening calendar

The values used

Name in the codeValueRoleWhere
SOON_DAYS60Notice: "soon" when 60 days or fewer remainsrc/trevor/lifecourse/screening.py:26
transcranial Doppler12 months, SS and Sβ0, ages 2 to 16Rhythm for these genotypesdata/screening_rules.json (exam doppler)
Brain MRIonce, SS and Sβ0, from age 5"Once" rhythmdata/screening_rules.json (exam irm_cerebrale)
eye exam, albuminuria12 months, from age 10All genotypesdata/screening_rules.json
cardiac ultrasound36 months, from age 18Pace per HUG; divergence with ASH 2019 flagged in the file notedata/screening_rules.json
ferritine3 months if transfusion, otherwise 12 monthsTwo rules in orderdata/screening_rules.json
ONCE_MONTHS1200A "once" exam counts as a century in the prevention plansrc/trevor/lifecourse/screening.py:25

What is shown

One line per exam with its pace, its state (up to date, soon, overdue, never, done, not recommended, not yet, team decides…), the due date and the last noted result. The prevention plan receives directives: drop, tighten the pace or pause reminders.

A worked example

Profile SS, age 20, hydroxyurea, eye exam entered on 12/20/2025: due 12/20/2026, 44 days left on 11/06/2026, so "soon" (calendar run). The Doppler does not apply at 20, the cardiac ultrasound and albuminuria are "never".

What this algorithm cannot do

Validation. Project rules table, declared "to be validated by the HUG hematology department" (data/screening_rules.json, status a_valider_hug, version 2026-10-21; docs/RELECTURES_A_FAIRE.md M-B1-1). Each rule carries internal references (R6, R25, R28, W9…) pointing to docs/ETAT_DE_L_ART_MODIFICATION_MALADIE.md.

Code : src/trevor/lifecourse/screening.py (rule_for, calendar, remindable, prevention_directives, age_range), src/trevor/lifecourse/screening_store.py (profile_for, calendar_for, directives), src/trevor/conversation/screening_reminders.py, data/screening_rules.json

Stress load and resources ("balance")

Trévor adds load points (stress, mood, PHQ-9, GAD-7, life events) and resource points (good things noted, supports, mood, calm) over 30 days and shows them side by side as two percentages. It is a project index with no clinical validation.

Where you see it: "My mental health" > Go further > Trends.

What the algorithm reads

The calculation, step by step

Load points (maximum 8)Average stress ≥ 7: +2; 4 to 6.99: +1Average mood ≤ 4: +2; 4.01 to 6: +1PHQ-9 ≥ 10: +2; 5 to 9: +1GAD-7 ≥ 10: +2; 5 to 9: +1More pathogenic than salutogenic life events: +1Resource points (maximum 6)At least 3 good-thing notes: +2; 1 or 2: +1At least 3 supports: +1Life events present with salutogenic ≥ pathogenic: +1Average mood ≥ 7: +1Average stress ≤ 3: +1PercentagesLoad = 100 × points ÷ 8, roundedResources = 100 × points ÷ 6, roundedLevelsLoad: 60 and above high; 30 to 59 moderate; under 30 lowResources: 60 and above solid; 30 to 59 present; under 30 to buildLoad ≥ resources?yesnoAdvice: reduce the loadAdvice: strengthen supports
Flowchart: Stress load and resources ("balance")

The values used

Name in the codeValueRoleWhere
maximum load8Denominator of the load percentagesrc/trevor/conversation/mental_health.py:755
maximum resources6Denominator of the resources percentagesrc/trevor/conversation/mental_health.py:756
level thresholds60 and 30Level limits for load and resourcessrc/trevor/conversation/mental_health.py:757-758
window30 daysPeriod of averages and notessrc/trevor/conversation/mental_health.py:702

What is shown

Two levels and two percentages, the list of factors that weigh and those that protect, and a piece of advice. With no data at all, a message says there is not enough data.

A worked example

Average stress 5 (+1), average mood 4 (+2), PHQ-9 of 12 (+2), GAD-7 of 3 (0), no event: load 5 points out of 8, so 62% (62.5 rounded to 62), high level (checked by calculation).

What this algorithm cannot do

Validation. "Transparent" index invented by the project, inspired by the idea of allostatic load and the salutogenic approach (Antonovsky, cited in the code). The weights and thresholds have no source in the code and were not validated.

Code : src/trevor/conversation/mental_health.py (allostatic_balance, _balance_block, finish_mh_mood)

Short screeners: post-traumatic stress, ADHD, autism

Trévor counts your answers to three short questionnaires (PC-PTSD-5, ASRS v1.1 part A, AQ-10) and says whether the screen is "positive", which means a professional opinion is suggested. This is not a diagnosis or a validated medical device: the result points you toward a professional.

Where you see it: "My mental health" > Self-check.

What the algorithm reads

The calculation, step by step

PC-PTSD-5If you did not report exposure to an event: no score, dedicatedmessageOtherwise: number of "Yes" among the 5 itemsPC-PTSD-5: at least 3 "Yes"?yesnoPositive screen, withhelplinesNegative screenASRSEach item counts if it reaches its zone: items 1 to 3 from"Sometimes", items 4 to 6 from "Often"ASRS: at least 4 of 6 itemsin the zone?yesnoPositive screenNegative screenAQ-10One point per "agree" item (items 1, 7, 8, 10: Definitely orSlightly agree) and per "disagree" item (items 2, 3, 4, 5, 6, 9:Slightly or Definitely disagree)AQ-10: 6 points or more?yesnoPositive screenNegative screen
Flowchart: Short screeners: post-traumatic stress, ADHD, autism

The values used

Name in the codeValueRoleWhere
ASRS_THRESHOLD{0: 2, 1: 2, 2: 2, 3: 3, 4: 3, 5: 3}Minimum answer position for the item to countsrc/trevor/conversation/mental_health.py:58
ASRS threshold4 out of 6Positive screen from 4 itemssrc/trevor/conversation/mental_health.py:191-195
AQ_AGREE_ITEMS / AQ_DISAGREE_ITEMS{0,6,7,9} / {1,2,3,4,5,8}Items scored when you agree, or disagree (Allison 2012 key per the code)src/trevor/conversation/mental_health.py:60-61
AQ-10 threshold6Positive screen from 6 pointssrc/trevor/conversation/mental_health.py:688
PC-PTSD-5 threshold3Positive screen from 3 "Yes"src/trevor/conversation/mental_health.py:662

What is shown

A score (PC-PTSD-5 out of 5, ASRS out of 6, AQ-10 out of 10) and a "positive" or "negative" message with an explanation. This is not a diagnosis or a validated medical device: the result points you toward a professional.

A worked example

No numeric example was run for this card.

What this algorithm cannot do

Validation. Thresholds and keys of the published instruments as the code mentions them (ASRS per WHO, AQ-10 Allison 2012 key). The repository holds no local validation or clinical review of the advice.

Code : src/trevor/conversation/mental_health.py (pcptsd_count, asrs_positive, aq10_score, _finish_pcptsd, _finish_asrs, _finish_aq10)

Depression and anxiety: PHQ-9, GAD-7 and Edinburgh scale

Trévor adds up your answers to the PHQ-9 (mood), GAD-7 (anxiety) and, during the postpartum period, the Edinburgh scale (EPDS). It gives a score, a level and advice, and always handles first any answer that suggests thoughts of self-harm. This is not a diagnosis or a validated medical device: the result points you toward a professional.

Where you see it: "My mental health" > Self-check. The EPDS comes first if you are postpartum.

What the algorithm reads

The calculation, step by step

Points per answerPHQ-9 and GAD-7: Never 0, Several days 1, More than half the days2, Nearly every day 3A missing or unknown answer: no score, "incomplete" messageSumPHQ-9: sum of 9 answers, 0 to 27GAD-7: sum of 7 answers, 0 to 21EPDS: sum of 10 items scored 0 to 3, 0 to 30; items 3 and 5 to 10are reversed (displayed from most to least severe)PHQ-9: question 9 differentfrom "Never"?yesnoSupport message and helplinesBEFORE the resultNo safety messageEPDS: question 10 differentfrom "Never"?yesnoSame support message, beforethe resultNo safety messageLevel (PHQ-9)0 to 4 minimal; 5 to 9 mild; 10 to 14 moderate; 15 to 19moderately severe; 20 and above severeLevel (GAD-7)0 to 4 minimal; 5 to 9 mild; 10 to 14 moderate; 15 and abovesevereLevel (EPDS)Under 10: low; 10 to 12: possible depression; 13 and above:probable depressionAdvicePHQ-9, GAD-7 and EPDS: from 15 (EPDS: 13) advice to see aprofessional; 10 to 14 (EPDS: 10 to 12) intermediate advice;below, light adviceThe score and a summary sentence are saved with your answer
Flowchart: Depression and anxiety: PHQ-9, GAD-7 and Edinburgh scale

The values used

Name in the codeValueRoleWhere
FREQ_SCALE[Never, Several days, More than half the days, Nearly every day]PHQ-9 and GAD-7 answer scale (0 to 3)src/trevor/conversation/mental_health.py:53
EPDS_REVERSED_ITEMS{2, 4, 5, 6, 7, 8, 9}Reversed EPDS items (0-based indices)src/trevor/conversation/mental_health.py:64
EPDS_POSSIBLE, EPDS_PROBABLE10, 13EPDS thresholdssrc/trevor/conversation/mental_health.py:65
PHQ-9 thresholds4 / 9 / 14 / 19Upper limits of the minimal, mild, moderate, moderately severe levelssrc/trevor/conversation/mental_health.py:169-178
GAD-7 thresholds4 / 9 / 14Upper limits of the minimal, mild, moderate levelssrc/trevor/conversation/mental_health.py:181-188
advice thresholds15 and 10"See a professional" advice from 15, intermediate advice from 10src/trevor/conversation/mental_health.py:605-609

What is shown

A score (PHQ-9 out of 27, GAD-7 out of 21, EPDS out of 30), its level in words and advice. Answers suggesting suicidal thoughts trigger a support message with your country's helplines before anything else. This is not a diagnosis or a validated medical device: the result points you toward a professional.

A worked example

PHQ-9 with "Several days" for all 9 questions: 9, mild level; with 5 answers "More than half the days" and 4 "Several days": 14, moderate level (checked by running phq9_score). GAD-7 with "Several days" everywhere: 7, mild level. EPDS: score 11 → "possible depression".

What this algorithm cannot do

Validation. The scoring keys are those of known instruments (the code calls them "based on validated instruments" and cites Cox 1987 and Guedeney 1998 for the EPDS, HAS 2014 and NICE CG192 for its postpartum use). The repository shows no clinical validation of the French wording or of the advice.

Code : src/trevor/conversation/mental_health.py (phq9_score, gad7_score, phq9_band, gad7_band, epds_item_scores, epds_band, _finish_phq9, _finish_gad7, _finish_epds)

Hydroxyurea follow-up test reminder

Trévor works out the date of your next follow-up test by adding the pace your doctor gave you to the date of the last known test. It never suggests a pace itself and sends no reminder until you have entered one.

Where you see it: "Regularity and follow-up tests" screen (test line), and a reminder message attached to the gentle prevention reminder.

What the algorithm reads

The calculation, step by step

Is a pace entered?yesnoWe look for the last testState "unset": no due date,no reminderLast known testThe most recent of the date noted by hand and the latest HbF orhemoglobin measurement in the recordIs a date known?yesnoDue date = last test + pace(in months, day clipped tomonth end if needed)State "no date": a singlereminder asks you to enterthe dateIs today past the due date?yesnoState "overdue"30 days or fewer left? Yes:"soon"; no: "up to date"ReminderOnly "no date", "soon" and "overdue" produce a reminderOne reminder per due date (marker = due date), attached to theprevention message
Flowchart: Hydroxyurea follow-up test reminder

The values used

Name in the codeValueRoleWhere
rhythm_months[1, 2, 3, 4, 6]Accepted paces; any other number is refuseddata/hydroxyurea.json:12
soon_days30Notice: "soon" when 30 days or fewer remaindata/hydroxyurea.json:13
kinds["hbf", "hb"]Record measurement types that count as a testdata/hydroxyurea.json:14
date limit5 yearsA noted test cannot be in the future or more than 5 years oldsrc/trevor/hydroxyurea.py:135

What is shown

Five states: unset, no date, up to date, soon (30 days or fewer), overdue. Each has its own sentence. All except "up to date" and "unset" trigger a single reminder per due date.

A worked example

Pace 3 months, last test on 08/15/2026: due on 11/15/2026; on 11/06/2026 there are 9 days left, so "soon" (computed by hand from add_months and the 30-day threshold).

What this algorithm cannot do

Validation. Organizational rule of the project, with no clinical threshold: the pace is your doctor's. List of paces and 30-day notice: "to be validated by the HUG" (docs/RELECTURES_A_FAIRE.md, M-B2.1 and M-B2.2).

Code : src/trevor/hydroxyurea.py (labs_status, last_lab_date, add_months, reminder_text, reminder_pending, mark_labs_done, set_rhythm), src/trevor/conversation/reminders.py (prevention_due_reminders), data/hydroxyurea.json

Hydroxyurea in the crisis risk

When you take hydroxyurea, your regularity over the last 84 days becomes two features of the risk model: a protective one and an "irregular intake" one. This card describes only that input, not the full risk calculation, which has its own card.

Where you see it: Indirectly: in the reasons shown with the crisis risk (for example "Hydroxyurea taken irregularly").

What the algorithm reads

The calculation, step by step

Do you take hydroxyurea?yesnoWe read the regularityhu_protect = 0 and hu_gap = 0Regularity unknown or ≥ 80%?yesnohu_protect = 1, hu_gap = 0We look at the next bandRegularity 60 to 79%?yesnohu_protect = 0.6 and hu_gap =0.4Under 60%: hu_protect = 0 andhu_gap = 1Entry into the modelPrior weights: hu_protect −0.55; hu_gap +0.45These two weights are not multiplied by the 1.6 gain applied torisk factorsA trained personal model can replace these weights
Flowchart: Hydroxyurea in the crisis risk

The values used

Name in the codeValueRoleWhere
good threshold80From 80%: full protectionsrc/trevor/wearables/crisis.py:297
medium threshold6060 to 79%: protection 0.6 and gap 0.4src/trevor/wearables/crisis.py:299
RISK_GAIN1.6Gain applied to the other risk factorssrc/trevor/wearables/crisis.py:493
GAIN_EXEMPThu_protect, dmt_other, tx_recent, tx_protectProtective features that are not amplifiedsrc/trevor/wearables/crisis.py:495

The weights

A positive weight raises the result, a negative weight lowers it.

SignalWeightWhere
Hydroxyurea taken regularly (≥ 80% or unknown)−0.55src/trevor/wearables/crisis.py:78
Hydroxyurea taken irregularly+0.45src/trevor/wearables/crisis.py:78

What is shown

Two numbers between 0 and 1 (hu_protect and hu_gap) that enter the model sum. An "hydroxyurea" reason appears with the risk if it weighs enough.

A worked example

Regularity 79%: hu_protect 0.6, hu_gap 0.4; 59%: 0 and 1; 80%: 1 and 0 (checked by running treatment_features).

What this algorithm cannot do

Validation. The weights are code priors, commented as drawn from the hydroxyurea literature (Charache 1995, MSH study; Ware 2016, cited in the comment at src/trevor/wearables/crisis.py:70-77) but "replaced by those learned on the person and the cohort" and not validated. The 60% and 80% bands have no source in the code.

Code : src/trevor/wearables/crisis.py (treatment_features, PRIOR_WEIGHTS, GAIN_EXEMPT), src/trevor/wearables/service.py (treatment_context, training_rows), src/trevor/hydroxyurea.py (pdc, pdc_from_days)

Hydroxyurea regularity (days covered)

Trévor counts, over the last 12 weeks, the share of logged days on which you took your hydroxyurea. This percentage helps you see how regular you are and feeds other indicators (crisis signal, crisis risk). It is not a validated medical device and it does not judge how you take your treatment.

Where you see it: The "Regularity and follow-up tests" screen of the bot and the /api/phone/hydroxyurea route of the app, for people who have hydroxyurea among their treatments.

What the algorithm reads

The calculation, step by step

Find your hydroxyureaThe tracking key is "hydroxyuree", or an entered medicine withthat nameOnly accounts with the "patient" role are concernedIs there daily tracking?yesnoThe days logged over the last84 days are read, assumeddoses includedIf the medicine is only inyour pharmacy list, the pageexists but the regularitystays emptyCountlogged = window days that have a row (taken or missed), up totodaycovered = among them, the days marked takenA day with no row is neither taken nor missed: it is not countedAt least 14 logged days?yesnoRegularity = covered ÷ logged× 100, rounded to a wholenumberNo percentage: Trévor sayshow many days are logged andthat 14 are neededCount your own actions"declared" = days logged by an action of yours (without assumeddoses)If declared < logged, a line explains that a day "taken bydefault" counts as taken until you report a missed doseRegularity ≥ 80%?yesno"good" = true (this flag isused by the crisis signal)"good" = falseDisplay"Over the last 84 days, your treatment is logged as taken X daysout of Y (Z %)"Reasons for missed doses (your own actions only) feed consultationpreparation
Flowchart: Hydroxyurea regularity (days covered)

The values used

Name in the codeValueRoleWhere
window_days84Calculation window: 12 weeks, current day includeddata/hydroxyurea.json:7
min_logged_days14Minimum logged days to show a percentagedata/hydroxyurea.json:8
good_from_percent80Threshold from which regularity is called "good"data/hydroxyurea.json:9
a_validertrueThe parameter file declares itself "to be validated by the HUG"data/hydroxyurea.json:4

What is shown

A whole-number percentage from 0 to 100 (or nothing under 14 logged days), the number of covered, logged and declared days, and a "good" flag from 80%. The 60% threshold does not exist here: it appears only in the crisis risk calculation (card "Hydroxyurea in the crisis risk").

A worked example

With 30 logged days of which 22 taken (one day in four missed), regularity = 22 ÷ 30 = 73% (checked by running pdc_from_days). With only 10 logged days, all taken, the result is "no percentage" because 10 < 14.

What this algorithm cannot do

Validation. Values set by the project team and marked "to be validated by the HUG" (data/hydroxyurea.json:3-4; docs/RELECTURES_A_FAIRE.md, line M-B2.3, status "to be validated by the HUG"). The code cites no reference for the window, the 14-day minimum or the 80% threshold. The principle "days covered over days observed" is a common way to measure adherence, but this repository does not establish it.

Code : src/trevor/hydroxyurea.py (pdc_from_days, pdc, hu_key, missed_reasons, lines), data/hydroxyurea.json, src/trevor/navigator/doses.py (fill_defaults), src/trevor/storage/database.py (adherence_days)

"Worth discussing with your team" signal (HbF or crises)

Trévor spots two situations worth raising with your care team: an HbF that stays under your own best level over three measurements, or at least three crises in six months despite regular intake. It never concludes that the treatment does not work and proposes no change.

Where you see it: "Regularity and follow-up tests" screen and consultation questions. The signal is never sent as a notification.

What the algorithm reads

The calculation, step by step

Sort HbF measurementsFrom oldest to newestAt least 3 measurements?yesnoWe compareNo HbF signalTwo conditionsBelow best: the last value (rounded to 0.1) is strictly under thehighest of the previous onesNot rising: over the last three, each is lower than or equal tothe previous oneAre both conditions true?yesno"hbf" signalNo HbF signalCount crisesCrisis episodes whose start day is in the last 180 daysAt least 3 crises ANDregularity ≥ 80% over ≥ 28logged days?yesno"crises" signalNo crises signalDisplayThe reasons for the signal, then always the sentence "worthdiscussing with your care team"No signal is shown without that sentence
Flowchart: "Worth discussing with your team" signal (HbF or crises)

The values used

Name in the codeValueRoleWhere
min_hbf_measures3Minimum HbF measurementsdata/hydroxyurea.json:17
min_logged_days_for_adherence28Minimum logged days to judge regularity in this signaldata/hydroxyurea.json:18
crises_min3Number of crises that triggers the signaldata/hydroxyurea.json:19
crises_window_days180Crisis counting window (shown as "6 months")data/hydroxyurea.json:20
good_from_percent80Same regularity threshold as the "Regularity" carddata/hydroxyurea.json:9

What is shown

A list of signals ("hbf", "crises", both or none). Each signal shows its reason (the number of crises is quoted) then the footer sentence "worth discussing with your care team". A consultation question is added if a signal exists.

A worked example

HbF logged 8, 12, 10, 9.5: last 9.5 < best 12 and 12 → 10 → 9.5 does not rise, so signal (checked with hbf_vs_best). With only 8 and 12, count = 2, no signal.

What this algorithm cannot do

Validation. Rules set by the project team and "to be validated by the HUG" (docs/RELECTURES_A_FAIRE.md, M-B2.4 and M-B2.5, which ask precisely whether 3 crises in 6 months, 80% and a strict drop are suitable). No study is cited in the code.

Code : src/trevor/hydroxyurea.py (non_response, signal_lines, consult_questions), src/trevor/royal/labs.py (hbf_series, hbf_vs_best), data/hydroxyurea.json

How a day is classed as a "crisis" day

Trévor decides whether a day counts as a crisis day from what you logged: severe pain, hospitalization, a declared crisis episode. This label is then used to train the risk model, to spot trends and to test associations. The rules are not identical in every module.

Where you see it: Not shown as such: the label feeds the crisis risk, trends ("My indicators"), charts and associations. The crisis journal shows you the episodes you declare.

What the algorithm reads

The calculation, step by step

Daily follow-upPain ≥ 7 out of10, or"hospitalized"answer: crisis dayPain outside thequestionnaireIntensity ≥ 7 ANDtext or categorycontaining crise,urgence, hospital,cvo or vaso:crisis dayCrisis journalEvery day of theepisode, fromstart to end (oruntil today ifongoing): crisisdayDaily painIf you answer "no pain", the day's pain is 0 (known data, notmissing)Several sources the same day: the highest value is keptCrisis day in the riskmodel: crisis today orwithin the next 2 days?yesnoTraining label = 1Training label = 0Other usesCharts and associations (series.py): 1 for episode days and dayswith pain ≥ 7, 0 for other days on which you logged pain, mood orfatigueTrends (insights.py): only journal episode daysAssumed "all is well" days: crisis and hospitalization daysexcludedCircle alertWhen an episode is saved: maximum pain ≥ 7 or care "ER" or"hospital" → Trévor offers to alert your support circle
Flowchart: How a day is classed as a "crisis" day

The values used

Name in the codeValueRoleWhere
pain threshold7Pain from 0 to 10 that makes the day a crisis daysrc/trevor/wearables/service.py:553
CRISIS_OBS_WORDS("crise", "urgence", "hospital", "cvo", "vaso")Words that, with pain ≥ 7 logged outside the questionnaire, make the day a crisissrc/trevor/wearables/service.py:513
HORIZON_DAYS2The training label is 1 if a crisis occurs today or in the next 2 dayssrc/trevor/wearables/crisis.py:123
pain threshold (charts)7Same threshold in the chart and association seriessrc/trevor/navigator/series.py:157
circle alert threshold7Maximum pain from which the circle alert is offeredsrc/trevor/conversation/crisis_diary.py:178

What is shown

For each day: crisis yes/no, with the day's maximum pain. The risk training label also looks at the next 2 days.

A worked example

A day on which you log pain of 7/10: crisis day (7 ≥ 7). The day before and the one before that receive training label 1 when the signals of those days are learned. Pain of 6/10 with no hospitalization or episode is not a crisis day.

What this algorithm cannot do

Validation. Threshold of 7 out of 10 set by the project team as a severe-pain marker; the code cites no study for this choice. The 2-day horizon is a design choice of the risk model, not validated.

Code : src/trevor/wearables/service.py (day_records), src/trevor/wearables/crisis.py (training label), src/trevor/navigator/series.py (build), src/trevor/conversation/insights.py (_crisis_days), src/trevor/conversation/crisis_diary.py, src/trevor/dashboard/data.py (daily_series)

Reminder the day before your crisis-prone weekday

If at least 5 of your crises over the last 120 days cluster on the same weekday, Trévor spots that day so it can send a self-care reminder the day before. It relies only on your own journal.

Where you see it: Self-care reminder message the day before the dominant weekday. Reserved for patients whose condition has crisis prediction and who enabled crisis alerts; at most one message every 7 days (reminders.py:1416-1450).

What the algorithm reads

The calculation, step by step

CountStart of each crisis of the last 120 days sorted by weekdayAt least 5 crises?yesnoWe look for the most frequentweekdayNo dominant weekdayDoes that day have at leastmax(3; 1.5 × crises ÷ 7)crises?yesnoDominant weekday (0 = Monday)No dominant weekdayReminder the day beforeIf tomorrow is the dominant weekday, the condition has crisisprediction, crisis alerts are on and the last reminder is at least7 days old: a self-care message names the day
Flowchart: Reminder the day before your crisis-prone weekday

The values used

Name in the codeValueRoleWhere
MIN_CRISES5Minimum crisessrc/trevor/conversation/prevention.py:16
WINDOW_DAYS120Windowsrc/trevor/conversation/prevention.py:17
DOMINANCE1.5Share of dominant day in multiples of the uniform expectation (1/7)src/trevor/conversation/prevention.py:18

What is shown

A weekday, or none.

A worked example

With 7 crises, the dominant day must have at least max(3; 1.5 × 7 ÷ 7) = 3. With 14 crises, at least max(3; 3) = 3; with 21 crises, at least 4.5 so 5 (computed by hand).

What this algorithm cannot do

Validation. "n-of-1" pattern set by the project team; thresholds not studied in the repository. The same rules (5 crises, 1.5) exist in insights.py (item 3).

Code : src/trevor/conversation/prevention.py (dominant_crisis_weekday), src/trevor/conversation/insights.py

Pain check after a rescue painkiller

45 minutes after you log a rescue painkiller dose, Trévor asks how the pain is and applies a three-level escalation protocol: call the emergency number (144 in Switzerland), go to the ER, or medical advice within 24 hours. The thresholds remain to be validated by hematology. This is not a validated medical device.

Where you see it: Neutral notification with no mention of pain (lock screen), then a question with four answers: better, same, worse, danger sign.

What the algorithm reads

The calculation, step by step

ScheduleAfter each dose: first check in 45 minutesAn episode that started less than 24 hours ago keeps its startDanger sign?yesnoCall the emergency number(144 in Switzerland) rightaway, without waiting for thepainkiller to act (level 1)We look at the answerWorse?yesnoER now (pain rising despitetreatment is an escalationcriterion)We continueSame?yesnoIf 1 hour or more since theepisode started, or ahigh-risk complication(stroke, pulmonaryhypertension, kidney): ER(level 2); otherwise a newcheck in 30 minutesBetter: we continueBetter: 20 hours or moresince the start?yesnoLevel 3: medical advicewithin 24 hours at mostNew check in 3 hoursOther answers"No more pain" ends the follow-up"Stop asking" turns the feature off; it is turned back on from therescue painkiller screen
Flowchart: Pain check after a rescue painkiller

The values used

Name in the codeValueRoleWhere
FIRST_CHECK45 minFirst check after the dosesrc/trevor/conversation/pain_check.py:35
SAME_RECHECK30 minNew check after "same"src/trevor/conversation/pain_check.py:36
BETTER_RECHECK3 hNew check after "better"src/trevor/conversation/pain_check.py:37
ESCALATE_AFTER1 hUnchanged pain after one hour: level 2src/trevor/conversation/pain_check.py:38
DAY_CEILING20 hPain still there: level 3src/trevor/conversation/pain_check.py:39
EPISODE24 hDuration of an episodesrc/trevor/conversation/pain_check.py:40
HIGH_RISK(stroke, pulmonary hypertension, renal)Complications that send you to the ER at the first "same"src/trevor/conversation/pain_check.py:41

What is shown

One message among: danger sign, worse, escalation, new check, better, 20-hour ceiling, pain gone, feature off. Your country's emergency number is inserted. Nothing is sent to a caregiver.

A worked example

Dose at 2:00 pm, check at 2:45 pm: "same" with 45 minutes elapsed and no complication → new check at 3:15 pm; "same" at 3:15 pm (1 h 15 elapsed) → ER (read from decide).

What this algorithm cannot do

Validation. The code describes the protocol as "the ER protocol in three levels" and its thresholds as "to be validated by hematology": set by the project, not validated.

Code : src/trevor/conversation/pain_check.py (arm, due, decide, _pain_high_risk), src/trevor/conversation/rescue.py (arm after a dose), src/trevor/conversation/reminders.py (pain_check_tick)

"Default" doses and treatment regularity rate

When you are in "exception" mode, Trévor shows your treatments as taken until you report a missed dose, and writes an "assumed" taken row overnight. The regularity rate of each treatment is then computed on logged days.

Where you see it: Treatments screen ("taken", "done" for a dressing), "My indicators", consultation summary, caregiver view.

What the algorithm reads

The calculation, step by step

Are you in "exception" modefor treatments?yesnoA daily treatment with no rowthat day shows as "taken bydefault"The explicit gesture frombefore is still neededEach nightFor the last 2 elapsed days, an assumed "taken" row is written foreach daily treatment with no rowNever before the first run (the first night sets the start)A spaced rhythm (deferoxamine, injection) is never assumed takenYour actions win"taken" or "missed dose" always replaces the assumed row"Undo" goes back to the default dosePossible reasons: forgot, unwell, no supply, side effects, away,otherIs the treatment daily?yesnoRate = days taken ÷ loggeddays over the window (30 daysusually), in %, and streak =consecutive days takenthrough todayRate = doses ÷ expected doses(at least 5 nights a week fordeferoxamine; one injectionevery n weeks), capped at100, no streakWhere assumed doses countCounted: your own displays, consultation summary, caregiver view,hydroxyurea regularityExcluded by default: correlations, associations, adherence/crisistrends, points
Flowchart: "Default" doses and treatment regularity rate

The values used

Name in the codeValueRoleWhere
CATCHUP_DAYS2Elapsed days filled in each nightsrc/trevor/navigator/doses.py:24
REASONS(forgot, unwell, no_supply, side_effects, away, other)Reasons for a missed dosesrc/trevor/navigator/doses.py:23
rate window30 days (default)Default window of the adherence ratesrc/trevor/storage/database.py:6241
consultation threshold80Consultation question if the rate is under 80% with at least 7 logged dayssrc/trevor/conversation/consultation.py:42

What is shown

A state per day and per treatment (taken, assumed, missed with reason), a percentage rate, a streak of consecutive days and the number of assumed days.

A worked example

No numeric example was run for this card (the calculation needs a database).

What this algorithm cannot do

Validation. Organizational rules set by the project team. The 80% threshold for the consultation question is not justified in the code.

Code : src/trevor/navigator/doses.py (state, fill_defaults, declare_missed), src/trevor/storage/database.py (adherence_days, adherence_summary), src/trevor/navigator/checkin.py (inferred_taken)

Questions to ask your doctor

Trévor prepares up to five questions for your appointment from your recent data: crises, regularity, hydroxyurea signal, late transfusion, wound, overdue exams. Each question points to a topic to raise, never a diagnosis.

Where you see it: Consultation preparation and three points reused in team tasks (team_care.py:596-598).

What the algorithm reads

The calculation, step by step

At least 2 crises in 30days?yesnoQuestion about crisisfrequencyNothingAt least one crisis treatedin ER or hospital?yesnoQuestion on how to anticipatethe next oneNothingA daily treatment: at least7 logged days and rate under80%?yesnoQuestion about that treatmentNothingSpaced rhythmIf the rate (doses ÷ expected) is under 80%: question about therhythmHydroxyureaMost frequent reason for missed doses if it appears at least twiceInvitation to review if a signal existsLast transfusion: days ÷ 7 −interval ≥ 1 week?yesnoQuestion about the nextappointment (default interval4 weeks)NothingOrgans and woundOverdue or never-done exams: up to 3 namedWound not shrinking: question about the dressing or causeFill upWhile there are fewer than 5 questions, 3 general ones are added(vaccines and annual check-up, screening, who to call)
Flowchart: Questions to ask your doctor

The values used

Name in the codeValueRoleWhere
crises2Threshold for the frequency questionsrc/trevor/conversation/consultation.py:29
rated days / rate7 / 80Thresholds for the daily treatment questionsrc/trevor/conversation/consultation.py:42
transfusion delay1 weekDelay from which the question is askedsrc/trevor/conversation/consultation.py:58
maximum5Maximum number of questions after fillingsrc/trevor/conversation/consultation.py:85

What is shown

A list of questions written in French, filled up to 5 with general questions when fewer are found.

A worked example

No numeric example was run.

What this algorithm cannot do

Validation. Common-sense rules set by the project team, with no validated clinical threshold.

Code : src/trevor/conversation/consultation.py (suggested_questions), src/trevor/hydroxyurea.py (consult_questions)

Questionnaire scores: self-efficacy, quality of life, perceived usefulness

Trévor computes the score of several questionnaires: confidence in managing your condition (9 to 45), EQ-5D-5L quality of life, PedsQL quality of life (0 to 100) and perceived usefulness of Trévor (USE scale or short 3-question questionnaires). Each score is saved with your answer. These are not validated medical devices.

Where you see it: Result at the end of the condition-management questionnaire (with comparison to the average of people), quality-of-life questionnaire, category radar.

What the algorithm reads

The calculation, step by step

Does the questionnaire havea scoring scheme?yesnoThe scheme type chooses thecalculationNo scoreSelf-efficacy (sum_map)9 questions, from "Not at all confident" 1 to "Completelyconfident" 5; an unknown answer counts 0Sum from 9 to 45Confidence level42 and above: very high; 36 to 41: high; 27 to 35: average; under27: lowPer category (1 to 5): 5 very high; 4 high; 3 average; 1 or 2 lowCompared with the average of the bot's usersEQ-5D-5L5 dimensions (mobility, self-care, activities, pain, anxiety),each from 1 (no problem) to 5 by choice positionIf a dimension has no readable answer: no scoreIndex score with the national value set if the file exists,otherwise simplified score = 100 − 5 × (sum of levels above 1), 0to 100 (25 if all at level 5)PedsQLEach scale answer (Never … Almost always) is worth 100, 75, 50,25, 0 by positionTotal = mean of answered items, one decimal; no score if no answerPerceived usefulnessSum of numeric items (USE: 8 items from 1 to 7, 8 to 56; shortquestionnaires: 3 items from 1 to 7, 3 to 21)No score if an item is missing, is not an integer or is outside 1to 7
Flowchart: Questionnaire scores: self-efficacy, quality of life, perceived usefulness

The values used

Name in the codeValueRoleWhere
confidence bands[[42,very high],[36,high],[27,medium],[0,low]]Levels of the confidence score (out of 45)data/questionnaires/diseaseManagement.json (scoring.bands)
simplified EQ-5D-5L formula100 − 5 × sum(level − 1)Fallback score when the national value set is absentsrc/trevor/conversation/questionnaires/scoring.py:61-63
value setdata/scoring/eq5d5l_value_set.csv (not in the repository)Licensed EuroQol file to be provided; the repository contains only the READMEdata/scoring/README.md
PedsQL100 − position × 25Conversion of an answer to pointssrc/trevor/conversation/questionnaires/scoring.py:74
min_item / max_item1 / 7Bounds of perceived-usefulness itemsdata/questionnaires/useUtilite.json (scoring)

What is shown

One number per questionnaire. The EQ-5D-5L is labeled "simplified" when the value set is absent.

A worked example

EQ-5D-5L with levels 1, 2, 3, 1, 4: penalty 0 + 1 + 2 + 0 + 3 = 6, simplified score 100 − 30 = 70 (checked by running eq5d5l_score).

What this algorithm cannot do

Validation. The scoring follows published instruments (PedsQL: Varni's instrument licensed by Mapi, texts unmodified; USE: Lund 2001, translation "to be validated"). The confidence bands (42, 36, 27) are set in the data with no cited source; the code mentions an older category calculation. The EQ-5D-5L value set is not included.

Code : src/trevor/conversation/questionnaires/scoring.py (compute_score, sum_map_score, band_label, category_label, eq5d5l_score, eq5d5l_levels, choice_level, pedsql_score, sum_numeric_score), src/trevor/conversation/display.py (format_self_efficacy_score), data/questionnaires/*.json (scoring)

Medicine stock and reorder reminder

Trévor estimates how many treatment days you have left for each medicine and offers to prepare an order when stock gets low. It sends nothing to the pharmacy without your agreement.

Where you see it: "My medicines" ("order", "soon", "ok"), and an order reminder message.

What the algorithm reads

The calculation, step by step

Days per box and refill dateknown?yesnoDays left = days per box ×boxes − days since refill(minimum 0, at least one box)Level "unknown"Level7 days or fewer: order; 8 to 14 days: soon; more: okA medicine is to be orderedand no recent reminder?yesnoA message offers to preparethe orderNothingReminder cadenceNo reminder within 2 days after an order was sentAt most one reminder per medicine every 5 daysSafeguardsThe full preview always precedes sending and a second gestureauthorizes itThe email contains only identity, medicine and reply contactsAt most one send per medicine, recipient and day
Flowchart: Medicine stock and reorder reminder

The values used

Name in the codeValueRoleWhere
LOW_DAYS7Order from 7 days or fewersrc/trevor/conversation/pharmacy.py:52
SOON_DAYS14Soon from 14 days or fewersrc/trevor/conversation/pharmacy.py:53
rappel5 days / 2 daysGap between reminders / pause after an ordersrc/trevor/conversation/reminders.py:1470-1472
MAX_BOX_DAYS / MAX_BOXES365 / 99Entry boundssrc/trevor/conversation/pharmacy.py:54-55

What is shown

A number of days left, a level (order, soon, ok, unknown) and a reminder message that names the medicine and the number of days.

A worked example

Box of 30 days, 2 boxes, refill 55 days ago: 30 × 2 − 55 = 5 days left, level "order" (days_left calculation read from the code).

What this algorithm cannot do

Validation. Thresholds of 7 and 14 days set by the project team as an ordering margin; no clinical validation, with no direct therapeutic stake.

Code : src/trevor/conversation/pharmacy.py (days_left, level, to_order, public), src/trevor/conversation/reminders.py (pharmacy_nudges)

Perceived stress: PSS-10 scale and daily feeling

Trévor computes your score on the PSS-10 perceived stress scale (0 to 40) and gives it a level, then reacts to your daily feeling (0 to 10) with advice. The questionnaire cannot be retaken within 14 days. This is not a diagnosis or a validated medical device: the result points you toward a professional.

Where you see it: "My stress": daily feeling, PSS-10, trends.

What the algorithm reads

The calculation, step by step

Points per answerNever 0, Almost never 1, Sometimes 2, Fairly often 3, Very often 4Items 4, 5, 7, 8 reversed (4 minus the point)10 readable answers?yesnoScore = sum, 0 to 40No score: "incomplete"messageLevel0 to 13: low; 14 to 26: moderate; 27 and above: highScore ≥ 27?yesnoStrong advice and helplines14 to 26: moderate advice;under 14: light adviceDaily feelingLevel ≥ 8: support message and helplinesAdvice: a language-model text if available and containing noinvented health number, otherwise a simple rule: 0 to 3 lightadvice, 4 to 7 intermediate, 8 to 10 strong
Flowchart: Perceived stress: PSS-10 scale and daily feeling

The values used

Name in the codeValueRoleWhere
PSS_SCALENever 0 ... Very often 4Points per answersrc/trevor/conversation/stress.py:45
PSS_REVERSED{3, 4, 6, 7}Reversed items (0-based indices)src/trevor/conversation/stress.py:46
PSS-10 thresholds13 and 26Upper limits of the low and moderate levelssrc/trevor/conversation/stress.py:82-87
minimum delay14 daysA new attempt is refused before 14 dayssrc/trevor/conversation/stress.py:141

What is shown

A score out of 40, a level and advice. The daily feeling gives advice and, from 8 out of 10, the helplines. This is not a diagnosis or a validated medical device: the result points you toward a professional.

A worked example

All answers "Sometimes": each item is 2, reversed 4 − 2 = 2, so 20 out of 40, moderate level (checked by running pss_score).

What this algorithm cannot do

Validation. The PSS-10 is a published instrument; reversing items 4, 5, 7 and 8 matches its usual key. The low, moderate and high levels and the advice have no source cited in the code nor visible clinical review.

Code : src/trevor/conversation/stress.py (pss_score, pss_band, finish_pss10, finish_stress_checkin, _stress_recommendation)

Spaced "how are you?" and assumed values

Trévor does not ask you every day how you are. By default it assumes all is well as long as you say nothing, and asks one short question from time to time, more spaced out when you answer "good". Assumed days are never used as evidence.

Where you see it: "How are you?" message with three answers (good, so-so, not good); assumed days are marked "assumed" in charts and tracking.

What the algorithm reads

The calculation, step by step

Mode per domainIf you chose: your choiceOtherwise "daily" for people who already had a daily reminder(pain, mood, water), "exception" for othersTreatments stay in "exception" by defaultShould the question be askedtoday?yesnoYes if: patient with finishedonboarding and not blocked,pain or mood in "exception",fewer than 3 ignoredreminders, no ongoinghospital stay, due datereached, last send at leastthe planned gap ago, andnothing logged for 7 daysNo question todayDo you answer "good"?yesnoThe good streak grows and thegap goes to 10, 14, 21 then28 daysThe streak resets to 0 andthe gap to 10 daysDo you answer "not good"?yesnoNew question in 3 days andthe usual follow-up may openNext question after theplanned gapRecord moodgood = 8, so-so = 5, not good = 3, saved as a mood out of 10 ("onetap")Assumed daysEach domain in "exception": from the first assumed day throughyesterday, excluding days you logged, crisis or hospitalizationdaysValues: pain 0, mood 8, water = your goal (8 glasses by default, 1to 20)Nothing is written to your record; these days are never used asevidence
Flowchart: Spaced "how are you?" and assumed values

The values used

Name in the codeValueRoleWhere
CHECKIN_EVERY_DAYS10Starting gap between two questionssrc/trevor/navigator/checkin.py:26
CHECKIN_MAX_EVERY_DAYS28Maximum gapsrc/trevor/navigator/checkin.py:27
CHECKIN_SCHEDULE(10, 14, 21, 28)Gap after 1, 2, 3, 4 "good" answers in a rowsrc/trevor/navigator/checkin.py:28
CHECKIN_AFTER_BAD_DAYS3Delay before the next question after "not good"src/trevor/navigator/checkin.py:29
SILENCE_DAYS7No question if you logged anything within these dayssrc/trevor/navigator/checkin.py:30
LEVELS{good: 8, mid: 5, bad: 3}Mood out of 10 saved for each answersrc/trevor/navigator/checkin.py:31
reminder_misses33 or more ignored reminders: no more questionssrc/trevor/navigator/checkin.py:181

What is shown

A spaced "how are you?" question, a mood out of 10 saved, and assumed "all is well" days (pain 0, mood 8, water at goal) displayed as assumed.

A worked example

First "good": gap of 10 days; second "good" in a row: 14 days; fourth and beyond: 28 days. A "not good" brings the next question back to 3 days (read from record_level).

What this algorithm cannot do

Validation. Design choice, motivated in the module header by literature observations on dropping adherence (figures 85.7% then 57.9% quoted in the code, source in docs/NAVIGATEUR_PERSONNEL.md). The gaps and assumed values have not been tested on patients in the repository.

Code : src/trevor/navigator/checkin.py (mode, checkin_due, record_level, assumed_days, assumed_values), src/trevor/navigator/series.py (build)

Prevention follow-up, vaccines and exam reminders

For each monitoring exam or vaccine you follow, Trévor computes the due date (last date + interval) and a state: up to date, soon, overdue or never entered. It sends a gentle reminder, only one per due date.

Where you see it: Prevention follow-up (✅ 🟡 🔴 ⬜), "My vaccines" summary, reminder message.

What the algorithm reads

The calculation, step by step

Starting intervalPrevention plan interval: 12 months by default if not statedPlan examples: check-up 12, eye exam 12, kidney 12, brain 60,heart-lung 36, gallbladder 24, pneumococcus 60, meningococcus 60,flu 12, ferritin (thalassemia) 3TightenA known complication can impose a tighter pace; the smaller winsKidney: max(3; 12 ÷ checks per year in the KDIGO grid) months whenthe stage is knownScreening calendarIf your genotype and age are known, the calendar interval (thetightest) replaces the plan's, and an exam that is not recommendedor not yet relevant disappearsIs there a last-exam date?yesnoDue = last exam + intervalState "never entered"Today ≥ due date?yesno"overdue"60 days or fewer: "soon";otherwise "up to date"Gentle reminder"Soon" or "overdue" exams whose due date was not already reminded:one message per person, attached to the hydroxyurea test reminderif anyPeople on pause excludedVaccines entered with "Add a vaccine": same rule; reminder after12, 60 or 120 months as you choose
Flowchart: Prevention follow-up, vaccines and exam reminders

The values used

Name in the codeValueRoleWhere
PREVENTION_SOON_DAYS60Prevention follow-up noticesrc/trevor/conversation/engine.py:2737
SOON_DAYS (vaccins)60Same notice for vaccinessrc/trevor/lifecourse/vaccine_log.py:40
PLAN_MONTHSflu 12; pneumococcus 60; meningococcus 60Usual pace of the plan's three vaccinessrc/trevor/lifecourse/vaccine_log.py:38
REMINDER_MONTHS(12, 60, 120)Possible reminders of a vaccine you addsrc/trevor/lifecourse/vaccine_log.py:39
_KDIGO_VISITSG1 (1,1,2) ... G5 (4,4,4)Checks per year by GFR and albuminuriasrc/trevor/lifecourse/complications.py:110

What is shown

One line per exam or vaccine: last date, due date, state (up to date, soon, overdue, never), and the reminder text "overdue" or "redo around DD.MM.YYYY".

A worked example

Last flu vaccine on 10/15/2025, interval 12 months: due 10/15/2026, on 11/06/2026 it is "overdue" (computed by hand with the rule today ≥ due).

What this algorithm cannot do

Validation. General markers drawn from follow-up recommendations, per the header of data/prevention.json ("to be confirmed with the team"); the kidney grid cites KDIGO 2012 in the code. Vaccine frequencies are not individually sourced in the code.

Code : src/trevor/conversation/engine.py (_prevention_rows_compute), src/trevor/lifecourse/vaccine_log.py (custom_rows), src/trevor/lifecourse/complications.py (exam_intervals, kdigo_visits_per_year), src/trevor/conversation/reminders.py (prevention_due_reminders), data/prevention.json

Insights on your crises and regularity

Over 120 days, Trévor compares the number of your crises this month and last month, your sleep before crises, the most frequent weekday, your regularity per treatment, and well- versus poorly-followed weeks. These are descriptive observations, never proof of cause.

Where you see it: Progress screen and a monthly digest sent at most once a month per person if at least one insight emerges (reminders.py:1380-1410). Crisis comparisons require the condition to have crisis prediction.

What the algorithm reads

The calculation, step by step

Window120 days ending today (Geneva day by default)At least 2 crises?yesnoCompare the last 30 days withthe previous 30: fewer ="decreasing", more ="increasing", equal ="stable"No trendAt least 15 measured nights,4 crises, 3 pre-crisisnights and 7 referencenights?yesnoAverage sleep gap betweenreference nights and the 2nights before a crisisstarts; if ≥ 40 min: messageNothingAt least 5 crises?yesnoMost frequent weekday if ithas at least max(3; 1.5 ×crises ÷ 7) crisesNothingRegularity per treatmentWith at least 10 logged days out of 30: ≥ 90% → "nice regularity";< 70% → "a daily reminder may help"Between 70 and 89%: no messageAt least 3 well-followed AND3 poorly-followed weeks?yesnoComplete weeks with at least5 logged days: good ≥ 80%,poor < 50%; if crisis daysper week differ by at least0.5 in favor of well-followedweeks: encouraging messageNothing
Flowchart: Insights on your crises and regularity

The values used

Name in the codeValueRoleWhere
WINDOW_DAYS120Analysis windowsrc/trevor/conversation/insights.py:24
MIN_CRISES_TREND2Minimum crises for a trendsrc/trevor/conversation/insights.py:25
MIN_CRISES_PATTERN4Minimum crises to look for a sleep patternsrc/trevor/conversation/insights.py:26
MIN_SLEEP_DAYS15Minimum measured nightssrc/trevor/conversation/insights.py:27
SLEEP_GAP_MINUTES40Sleep gap deemed notablesrc/trevor/conversation/insights.py:28
MIN_WEEKS_COMPARE3Minimum weeks in each groupsrc/trevor/conversation/insights.py:29
CRISIS_GAP_DAYS0.5Crisis-days-per-week gap deemed notablesrc/trevor/conversation/insights.py:30
regularity thresholds90 and 70"Nice regularity" and "a reminder may help" messagessrc/trevor/conversation/insights.py:137-140

What is shown

A list of messages with a tone (good, info, watch). Empty if nothing is reliable. The message about well-followed weeks reminds you it is a lead to confirm with your team, not a certainty.

A worked example

No numeric example was run (the calculation needs a database).

What this algorithm cannot do

Validation. Thresholds set by the project team, with no study cited in the code; messages present themselves as leads to discuss.

Code : src/trevor/conversation/insights.py (compute_insights, _weekly_adherence_and_crises)

Important. These calculations guide you; they make no diagnosis and do not replace the care team's advice. In case of severe pain, fever or shortness of breath, call 144 without waiting.