ADR-014: Problem-list-as-of-date for active_conditions / active_medications¶
Date: 2026-05-27
Status: Accepted
Amends: ADR-012 (the conditions/medications scoping sub-decision; the encounter grain is unchanged)
Contract impact: gold.encounter_summary v1.0.0 → v1.1.0 (MINOR)
Deciders: Sandeep Jayaprakash
Context¶
ADR-012 v1.0.0 scoped active_conditions / active_medications to the encounter where the
condition/medication was recorded (join on encounter_id). Synthea records a condition
once, so this left the corpus extremely sparse: avg 0.08 conditions and 0.05 medications
per encounter — most encounters showed an empty problem list even for patients with active
chronic disease. ADR-012 explicitly deferred a "problem-list-as-of-date" enrichment as a
future MINOR. This ADR makes that change, now that it's the chosen next priority for corpus
quality (the corpus feeds Ollama generation, scribe-iq RAG, and clinical-bert).
Inspecting real Coherent FHIR confirmed the temporal fields available (see ADR-013-style
data inspection): Condition.onsetDateTime (100%) and Condition.abatementDateTime (~32%,
the resolved ones); MedicationRequest.authoredOn + status, but no medication stop date
in FHIR (the STOP is only in the CSV, which is out of scope per ADR-013).
Decision¶
Compute both fields as the patient's clinical state as of each encounter's date, via a
patient-level join (no longer encounter_id-scoped):
active_conditions— a condition is active at an encounter whenonset_date <= encounter_dateand (abatement_dateis null orabatement_date > encounter_date). A chronic condition recorded once therefore carries forward to every later encounter; a resolved condition drops off after its abatement date. This required addingabatement_datetosilver.condition(fromCondition.abatementDateTime) — an additive Silver column.active_medications— astatus == "active"medication is active at an encounter when it was authored on/before the encounter date. Medications are pre-aggregated to one row per(patient, display)at their earliest start to keep the patient-level join small.
Both remain array[string] of distinct display names — same schema, changed semantics →
MINOR contract bump to 1.1.0 (CONTRACT_VERSION, regenerated JSON Schema, CORPUS_CONTRACT).
Consequences¶
- Positive: corpus grounding jumps to avg 9.57 conditions and 1.66 medications per encounter (from 0.08 / 0.05); only 0.9% of encounters now have an empty problem list (was the large majority). The lists are clinically coherent (e.g. Diabetes → diabetic renal disease → CKD co-occur). Conditions are temporally correct (onset + abatement gated).
- Accepted limitation (medications): FHIR carries no medication stop date, so
active_medicationsis a forward approximation — a med markedactiveshows from its authoring date onward, and a med that was active at a past encounter but later stopped is not reconstructable from FHIR alone. Documented in CORPUS_CONTRACT. (A precise med timeline would need the CSVSTOPcolumn — deliberately out of scope, ADR-013.) - Cost: the two aggregations become patient-level many-to-many joins (~1.7M condition
pairs, meds pre-deduped); Gold build stays well under the Silver step. Adding
abatement_daterequires a Silver rebuild. - Many Synthea "conditions" are SDOH/social factors (e.g. "Full-time employment", "Stress")
modeled as non-abating
Conditionresources, which inflates the average — expected and faithful to the source.
Alternatives considered¶
| Option | Pros | Cons | Why rejected |
|---|---|---|---|
| Problem-list-as-of-date (chosen) | Realistic grounding; temporally correct conditions | Med stop date unavailable in FHIR; needs a Silver column | Best fit; the planned ADR-012 MINOR |
| Keep encounter-recorded scoping (v1.0) | Simplest; no Silver change | Corpus near-empty (0.08/enc); weak grounding | The problem we set out to fix |
Use CSV START/STOP for precise med windows |
Exact med timeline | Mixes CSV into a FHIR-first lakehouse (contradicts ADR-013) | Out of scope; FHIR-first |
| Current-status snapshot (ignore dates) | Trivial | Not point-in-time; future conditions leak into past encounters | Temporally wrong |