What's New
This page summarizes the major changes in each release of FHIR4DS.
Version 0.0.13
August 2026
Version 0.0.13 is a reliability and integration release. It ships the post-0.0.12 reliability fixes, upgrades the medterm4ds integration to 0.0.3, and lands a broad QA hardening pass over the ingestion, error-handling, audit, installation, and API surfaces. The conformance baseline holds at 2832/2832 (ViewDefinition 144, FHIRPath 935, CQL 1706, DQM 47), now verified on the full CI invocation across Python 3.10 and 3.11 with fresh orjson.
Reliability fixes
- orjson 3.12 compatibility: deep-nesting decode recovery now matches both orjson depth-limit wordings (≤3.11 "recursion depth", 3.12+ "depth limit") instead of pinning a message — the published 0.0.12 wheel broke on orjson 3.12; 0.0.13 is the patch.
- DQM evaluator: population truthiness is numpy-safe (sequence
semantics instead of
bool()on array-likes — warns on old numpy, raises on new). - DQM CLI: runtime parameters are filtered to library-declared names (typos can no longer fail measures that never declared them).
- Recursion-limit import leak: the raised limit is scoped to script execution instead of leaking into every importer's process.
medterm4ds 0.0.3
- Bounded dependency bumped on both extras:
medterm4ds>=0.0.3,<0.0.4(terminology) andmedterm4ds[extraction]>=0.0.3,<0.0.4(ner). - The full integration surface (adapters, factory, ValueSet expansion with
the active-only/retired policy split, code search, annotation, the NER
notes pipeline) was diff-audited and re-verified against 0.0.3. Note:
medterm4ds 0.0.3 defaults its model revision to
v0.0.2(MEDTERM4DS_HF_REVISION) and adds device auto-detection (MEDTERM4DS_DEVICE).
Hardening highlights
- Native engine restorations: exact digit-string
div/mod(never binary64 mediators — values beyond 2^53 are exact), 2^63 literal contracts, named-group regexes ((?<name>…)+${name}substitution), leading inline regex flags, and PCRE$trailing-newline semantics. - FHIRPath validity contract: §6.7 temporal unit/precision violations now
classify as invalid in
fhirpath_is_validon both engines. - Loader error contracts: duplicate JSON members rejected per FHIR
json.html, lone-surrogate and non-JSON-native value guards, wrapped
closed-connection errors, BOM/URL parity, and a shared patient-reference
doctrine across the loader and
FileSystemSource(including versioned absolute references and list-valued references). FileSystemSourcedirectory paths work everywhere (scans and incremental delta scans), and bundle files are documented as inert rows.- API surface: README examples verified verbatim (including the
evaluate_measureDataFrame contract) and the full documented entry point set exercised on both engines.
Known limitation: five pre-release parity tests from a 0.0.12 release-commit source-loss incident remain carried (structural-type trio, ratio tuple comparison, WASM no-Python gate); they sit outside the 2832 conformance gate and the CI suite selection and are tracked for upstream tree recovery.
Version 0.0.12
August 2026
Version 0.0.12 ships the completed SQL-on-FHIR v2 spec-compliance
campaign (58 chunks across ViewDefinition, the Analytics Layer, CQL, and
FHIRPath), hardens the CQL translator (exact Decimal arithmetic,
age-uncertainty semantics, list/aggregate correctness, and query-level
Min/Max audit attribution), closes FHIRPath dual-engine parity work, and
upgrades the medterm4ds integration to 0.0.2 (bounded dependency
>=0.0.2,<0.0.3, retired-code policy split, in-process intensional ValueSet
expansion). Conformance rises to 2832/2832 across all four suites
(ViewDefinition 144, FHIRPath 935, CQL 1706, DQM 47).
New: SQLQuery / SQLView (the SQL-on-FHIR v2 Analytics Layer)
- FHIR
Libraryresources conforming to the SQLQuery and SQLView profiles: typed, FHIR-declared parameters, versioned SQL content, and canonical-URL dependencies that materialize as virtual tables. fhir4ds.sqlqueryshipsparse_library/parse_sqlquery/parse_sqlviewplusSQLQueryRunner, with typed errors for missing dependencies, dependency cycles, and parameter type mismatches.- See the sqlquery API reference for the profile model and a runnable example.
Data ingestion correctness
patient_refattribution now follows a single Patient-typed doctrine across the loader and file sources: only Patient-typed references (and bundle-localurn:uuid:) populate the patient identity — Group or Location subject references and bare ids no longer fabricate phantom patients in measure results.- Version-specific references (
Patient/123/_history/2) resolve to the current resource instead of silently dropping. - UTF-8 BOM-prefixed JSON/NDJSON files (common from Windows tooling) load
cleanly; case-variant extensions (
.JSON) and unreadable files no longer break or silently skip during directory loads. - Bundle entries are validated per-entry with index attribution; empty
entry.resourceobjects are rejected with a clear error. - Batch ingestion is ~70-150x faster (Arrow bulk path with automatic fallback); a 25,000-resource batch loads in ~0.3s.
Audit evidence and measure evaluation
- Min/Max aggregates over quantity queries now attribute the winning
resource in audit evidence (
Observation/xyz) with value and threshold — previously the evidence cited the aggregate value itself. - Quantity-typed aggregate references compare correctly (
MinBP < 140 'mmHg') instead of evaluating to false. audit_mode="full"output is one row per patient with the union of per-resource evidence (previously rows multiplied per evidence resource).evaluate_measurevalidatesoutput_columnsdefinition names and parameter names against the library — typos raise actionable errors instead of producing silently wrong results.
medterm4ds 0.0.2
- Dependency bound
medterm4ds>=0.0.2,<0.0.3on both theterminologyandnerextras; expansion behavior verified against the installed wheel. - Membership expansion includes retired codes for historical data while discovery/search stays active-only.
- In-process intensional ValueSet expansion (
?fhir_vs=isa/…) with graded code search (lexical/hybrid/semantic).
Version 0.0.11
August 2026
Version 0.0.11 introduces the medterm4ds integration — a three-phase pipeline that adds terminology services, auto-coding, and clinical NER to fhir4ds. The release also ships a spec-compliance sweep across the translator and the data-ingestion surfaces. Conformance holds at 2822/2822 across all four suites.
medterm4ds integration
The integration lands in three opt-in phases, each gated behind an install
extra so the core import fhir4ds path stays zero-dependency.
-
Phase 1 — Terminology Service (
pip install 'fhir4ds-v2[terminology]'): an env-driven factory (fhir4ds.cql.terminology.factory.get_terminology_endpoint) builds aTerminologyEndpointfromFHIR4DS_TERMINOLOGY_*env vars or an explicitTerminologyConfig. Two modes:http(any FHIR R4 terminology server, including the medterm4ds sidecar) andin_process(medterm4ds embedded directly — no HTTP hop). The endpoint exposesexpand(),search_text(),search_batch(), plus a per-instance circuit breaker for transient failures and a system-URL normalizer that expands UMLS mnemonics (SNOMEDCT_US) to FHIR canonical URLs (http://snomed.info/sct). See the Terminology Service docs. -
Phase 2 — Auto-Coding (same extra):
fhir4ds.cql.loader.auto_coder.AutoCoderaugments text-onlyCodeableConcepts (e.g.Condition.code.text) with codedCodings drawn from the terminology endpoint's top-k matches. The originaltextis preserved, existingcoding[]is never overwritten, every derivedCodingcarriesuserSelected=Falseand a structured autocoding extension (engine="medterm4ds", index version pinned). Cache keys are deterministic — re-running on the same input produces byte-identical output. See the Auto-Coding docs. -
Phase 4 — Clinical Notes Pipeline (
pip install 'fhir4ds-v2[ner]'):fhir4ds.cql.loader.notes_pipeline.NotesPipeline.extract_conditions()derives FHIR Condition resources from free-text note paths onClinicalImpression,DocumentReference,Encounter, and friends viamedterm4ds.extract()(medspaCy + GLiNER + SapBERT cascade). Each derived Condition carries aderived-from-textextension with source reference, note path, and span offsets for full audit. Deterministic IDs (sha256 of(source_ref, span_start, span_end, system, code)) make re-runs byte-identical. The heavy ML deps (medspaCy, transformers, torch) are owned transitively bymedterm4ds[extraction]— fhir4ds never imports them directly. See the Notes Pipeline docs.
medterm4ds is now declared as a normal PyPI dependency in the
[terminology] and [ner] extras — no sibling-repo install, no
--find-links pinning. The published wheel (medterm4ds 0.0.1 on PyPI)
exposes the canonical surface this release targets.
Additional hardening
A spec-compliance sweep across the translator and data-ingestion surfaces
closed 19 release-gate findings (QA-001 through QA-019) without altering
the public API: fluent-form CQL .distinct() now matches the function
form's NULL-preserving semantics; SQL-on-FHIR v2 forEachOrNull preserves
parent rows through nested iteration; the FHIR data loader and notes
pipeline gained strict input validation (Bundle.type attribution, NDJSON
strict-line attribution, malformed-URL/JSON guards); closed-connection /
malformed-URL / malformed-JSON errors now raise typed package exceptions
instead of leaking decoder/attribute/connection errors; audit_mode='full'
SQL emission now runs on 4 of 5 sampled CMS measures (CMS135, CMS165,
CMS71, CMS996) where it previously broke. Public __version__ is aligned
across all 7 subpackage __init__.py files.
Conformance
| Suite | Passed | Total | Rate |
|---|---|---|---|
| ViewDefinition v2 | 134 | 134 | 100.0% |
| FHIRPath R4 | 935 | 935 | 100.0% |
| CQL | 1,706 | 1,706 | 100.0% |
| DQM QI-Core 2025 | 47 | 47 | 100.0% |
| Overall | 2,822 | 2,822 | 100.0% |
Upgrade
pip install fhir4ds-v2==0.0.11
For the terminology tier: pip install 'fhir4ds-v2[terminology]'. For
clinical-notes NER: pip install 'fhir4ds-v2[ner]' (pulls
medterm4ds[extraction] transitively).
Version 0.0.10
June 2026
Version 0.0.10 is a release-preparation cycle focused on translator correctness for production CDS workflows and full release-readiness validation across package metadata, public docs, conformance baselines, benchmarks, and the release artifact surface.
Highlights
- Cross-Library Define References:
A."PatientAge"in a CQL library that usesincludeto reference another library now translates correctly in every usage context. The translator emits a correlated scalar subquery withLIMIT 1for SCALAR contexts (closing the binder error that previously affectedcase/ifconditions),EXISTSfor BOOLEAN contexts, and identity passthrough for LIST/query sources. Covered bytest_cross_library_reference.py(5 cases) andtest_definition_ref_parity.py(2 cases). The usage-aware translation strategy avoids the CTE-creation interception that caused an earlier draft of this fix to be reverted during release-prep. - Translator Correctness: Fixes a binder error when a CQL
case ... whenexpression references a previously-defined boolean define; the translator now emitsEXISTSagainst the boolean CTE instead of selecting a non-existentvaluecolumn.if ... then ... elseconditions benefit from the same fix. - Definition-Reference Consolidation: The two parallel code paths that
resolved promoted vs non-promoted definition references are now unified
through
_classify_definition_ref, closing a class of parity bugs and making the EXISTS-vs-correlated-subquery decision a single source of truth. - MedicationStatement Retrieve Fix:
[MedicationStatement: "X"]now resolves againstmedicationCodeableConcept(and themedicationReferencechoice-type alternative) instead of silently falling back to the non-existentcodefield. A full audit added 16 more FHIR R4 resource types whose primary code path is notcode. - FHIRPath
is()Empty-Collection Parity:is()now propagates the empty collection per FHIRPath §5.1 on both the native C++ engine (fn_isType) and the Python fallback (invocations/types.py), resolving the long-standingTestIsLowercaseTypes::test_empty_collection_returns_emptycase. Both paths now return the empty collection instead of[false]for non-FHIR-primitive type arguments. - FHIRPath Engine Hardening: Choice-type
as()andis()parity forvalue[x]on Parameters resources; bundled native extension refreshed (11.1 MB → 11.5 MB). - Release-Surface Alignment: Package metadata, public subpackage
versions, landing-page version, WASM wheel reference, install snippets,
and release notes are aligned with
0.0.10. - Validation Gates: The release-prep pipeline includes code review, release validation, documentation audit, benchmark validation, and final scribe handoff gates before completion. All four conformance suites (ViewDefinition, FHIRPath, CQL, DQM) remain at 100%.
Conformance
| Suite | Passed | Total | Rate |
|---|---|---|---|
| ViewDefinition v2 | 134 | 134 | 100.0% |
| FHIRPath R4 | 935 | 935 | 100.0% |
| CQL | 1,706 | 1,706 | 100.0% |
| DQM QI-Core 2025 | 47 | 47 | 100.0% |
| Overall | 2,822 | 2,822 | 100.0% |
Upgrade
pip install fhir4ds-v2==0.0.10
Version 0.0.9
June 2026
Version 0.0.9 is a release-preparation hardening cycle focused on preserving the full conformance baseline while revalidating infrastructure domains, release metadata, public documentation, browser assets, and benchmark evidence.
Highlights
- Release Readiness Campaign: Revalidates FHIRPath, CQL, SQL-on-FHIR ViewDefinition, ingestion/source adapters, DQM audit evidence, installation, and environment behavior across the scheduled 0.0.9 evolution loop.
- Version and Artifact Alignment: Package metadata, public subpackage
versions, notebook snippets, website install references, and WASM translator
wheel references are aligned with
0.0.9. - Validation Gates: The release-prep pipeline includes conformance, package pytest, documentation audit, benchmark validation, and final scribe handoff gates before completion.
Upgrade
pip install fhir4ds-v2==0.0.9
Version 0.0.8
June 2026
Version 0.0.8 focuses on Mongo-backed FHIR server integration, FHIR $cql
conformance-runner compatibility, release hardening, public API robustness,
audit evidence fidelity, and refreshed browser/package artifacts while
preserving the full conformance baseline.
Highlights
- Mongo FHIR Server Integration: Added
MongoFhirServerSourcefor read-only analytics over Mongo-backed FHIR servers through DuckDB's communitymongo_scanextension, with support for per-resource, explicit, and shared collection layouts. - Mongo DQM Materialization: Added
fhir4ds dqm mongo ...commands and worker support for durable patient-change queues, change-stream processing, result/audit storage, optional generatedMeasureReportpublishing, and patient-scoped source pushdown. - FHIR
$cqlFacade: Added a narrow local FHIR R4$cqloperation facade andfhir4ds cql-serverCLI for runningcqframework/cql-tests-runneragainst the FHIR4DS CQL engine. - CQL Spec Parity Sweep: Tightened CQL primitive, clinical, temporal, interval, list, quantity/ratio, conversion, rounding, and no-Python/native DuckDB parity behavior across the conformance surface.
- FHIRPath Native Parity: Native DuckDB FHIRPath now rejects malformed
Section 5.1 existence-helper arities, including specialized
exists()and FHIR-specifichasValue()dispatch paths, in parity with the Python fallback. - Measurement Period Fidelity: CQL-authored
Interval<DateTime>parameter defaults retain DateTime precision and authored open/closed boundary flags through DQM population SQL generation. - Public API Error Contracts: DQM config loaders, HAPI/Mongo materialization config parsing, and filesystem sources now raise actionable package errors for malformed public inputs.
- Audit Evidence Accuracy: Multi-group DQM audit pruning preserves group-local causal resource targets, and Mongo compact materialization now mirrors the HAPI compact result/full audit split.
- Release Artifact Consistency: Package metadata, public subpackage
versions, notebook snippets, CQL runner metadata, wheel contents, and WASM
translator assets are aligned with
0.0.8.
Bug Fixes
- CQL
$cqlRunner Compatibility: FHIRParametersserialization now handles intervals, empty/null values, temporal values, quantities, ratios, Codes, Concepts, Lists, and Tuples in runner-compatible shapes, and runner report status now reflects JSON-level failures even when the Node process exits successfully. - CQL Semantic Edge Cases: Fixed ratio literals, Long metadata
preservation, DateTime null precision, decimal equivalence, interval
null/open-bound behavior, interval uncertainty propagation,
ToStringformatting, and publicRound/RoundTohalf-away-from-zero behavior across Python fallback, native-loaded DuckDB, and no-Python/browser-style surfaces. - Measurement Period Fidelity: CQL-authored
Interval<DateTime>parameter defaults retain DateTime precision and authored open/closed boundary flags through DQM population SQL generation. - Public API Error Contracts: DQM config loaders, HAPI/Mongo materialization config parsing, and filesystem sources now raise actionable package errors for malformed public inputs instead of leaking decoder or attribute errors.
- Audit Evidence Accuracy: Multi-group DQM audit pruning preserves group-local causal resource targets, and Mongo compact materialization now mirrors the HAPI compact result/full audit split.
- Release Artifact Consistency: Package metadata, public subpackage
versions, notebook snippets, CQL runner metadata, wheel contents, website
release surfaces, and browser demo assets are aligned with
0.0.8.
Conformance
| Suite | Passed | Total | Rate |
|---|---|---|---|
| ViewDefinition v2 | 134 | 134 | 100.0% |
| FHIRPath R4 | 935 | 935 | 100.0% |
| CQL | 1,706 | 1,706 | 100.0% |
| DQM QI-Core 2025 | 47 | 47 | 100.0% |
| Overall | 2,822 | 2,822 | 100.0% |
Upgrade
pip install fhir4ds-v2==0.0.8
Version 0.0.7
May 2026
Version 0.0.7 focuses on release readiness, SQL safety, audit evidence accuracy, and packaging consistency. It preserves the 100% conformance posture while tightening loader boundaries, DQM population attribution evidence, and native/Python fallback release gates.
Highlights
- Compiled Measures API: Introduced
compile_measure()andexecute_compiled_measure()in the DQM API. This allows parsing and compiling CQL to SQL once, enabling highly efficient batched execution across patient cohorts. - Artifact Resolvers: Replaced static file-path dependencies with a pluggable
ArtifactResolverinterface (FileArtifactResolverandHapiArtifactResolver), enabling dynamic resolution of Measures, CQL libraries, and ValueSets from file systems or remote FHIR servers. - HAPI FHIR Integration: Added
HapiPostgresSourcefor querying HAPI FHIR JPA Server PostgreSQL backends in place, along with comprehensive guides for event-driven DQM materialization.
Bug Fixes
- FHIRPath Native Parity: Massively tightened the behavior of the C++ DuckDB extension to exactly match the Python fallback across arithmetic overflows, collection equality, singleton evaluation, string reflection, and edge-case Boolean precedence.
- CQL Type Inference: Fixed row shapes and nested tuples generated during compiled measure materialization so
QueryandReturnclauses preserve complex type structure correctly across batch runs. - CQL Optimization: Ensure degenerate intervals (e.g.
[x, x]) safely propagate throughStartsSameandEndsSametemporal operators without triggering DuckDB null-handling faults. - CQL Temporal Intervals: Optimized interval overlap SQL handles null low bounds using CQL interval semantics instead of propagating SQL NULL.
- DQM Audit Evidence: Exclusion-style audit narratives use effective population masks so denominator exceptions and numerator exclusions match final population attribution rules.
- Loader SQL Safety: Custom resource and ValueSet table names are quoted consistently, including SQL keywords such as
selectandwhere. - FHIR JSON Validation: File, URL, directory, and DQM ValueSet loaders now reject non-object JSON cleanly instead of leaking implementation errors.
Conformance
| Suite | Passed | Total | Rate |
|---|---|---|---|
| ViewDefinition v2 | 134 | 134 | 100.0% |
| FHIRPath R4 | 935 | 935 | 100.0% |
| CQL | 1,706 | 1,706 | 100.0% |
| DQM QI-Core 2025 | 47 | 47 | 100.0% |
| Overall | 2,822 | 2,822 | 100.0% |
Upgrade
pip install fhir4ds-v2==0.0.7
Version 0.0.6
May 2026
Version 0.0.6 focuses on release hardening, browser runtime parity, and clinical correctness for HEDIS/DQM workflows. The release preserves 100% conformance across ViewDefinition, FHIRPath, CQL, and DQM while tightening the packaged DuckDB extension boundary.
Highlights
- C++ DuckDB WASM Parity: Browser-required CQL interval, boundary, date/quantity, interval set, logical, list, valueset, and FHIRPath repeat functions are available through C++ extensions.
- No-Python Runtime Gate: Added direct-extension tests that load packaged C++ extensions without registering Python fallback UDFs.
- 100% Conformance Gate: ViewDefinition (134/134), FHIRPath R4 (935/935), CQL (1,706/1,706), and DQM QI-Core 2025 (47/47) all pass.
- HEDIS Clinical Logic: Calendar age helpers, episode aggregate folds, repeated-extension predicates, interval boundaries, stratifiers, and reference resolution were hardened for native DuckDB, Python fallback, and browser-style execution.
- DQM Reporting: Measure group stratifiers are parsed, evaluated, summarized, and exported in MeasureReport output.
- Packaging Safety: The wheel pins DuckDB to
1.5.2so installed Python dependencies match the bundled native extension ABI. - WASM Assets: Updated translator wheel to
fhir4ds_v2-0.0.6-py3-none-any.whland rebuilt DuckDB extension side modules.
Bug Fixes
- CQL: Patient-context
AgeIn*At(asOf)now routes throughCalculateAgeIn*At(birthDate, asOf)helpers for leap-day and calendar-period parity. - CQL: Query aggregate list folds preserve typed empty-list semantics so HEDIS episode deduplication counts episode collections correctly.
- CQL:
resolve()acceptsResourceType/id, bare ids, full URLs ending inResourceType/id, and JSON Reference objects. - DQM: Proportion summaries now assign patient/case population labels before aggregation so exclusions and exceptions are counted in the correct order.
- Sources: Strict NDJSON loading is all-or-nothing for both malformed JSON and valid-JSON invalid-FHIR records.
- CSV Source: Constructor inputs are validated at the public API boundary before SQL projection registration.
Upgrade
pip install fhir4ds-v2==0.0.6
Version 0.0.5
May 2026
Version 0.0.5 continues the 100% Compliance Milestone — every conformance suite passes at 100%, totaling 2,822 tests across CQL, FHIRPath, ViewDefinition, and DQM.
Highlights
- 100% Spec Compliance: All test suites now pass at 100% — CQL (1,706/1,706), FHIRPath (935/935), ViewDefinition (134/134), and DQM (47/47 measures).
- CQL Gap Closure: Resolved remaining 2 CQL spec tests —
RolledOutIntervals(DuckDB correlated UNNEST workaround) andIntegerIntervalProperlyIncludedInNullBoundaries(spec ambiguity resolved). - DQM Full Pass Rate: All 47 QI-Core 2025 CMS eCQMs now pass. 4 measures have documented upstream test data accuracy gaps (CMS135, CMS145, CMS157, CMS1017) that affect all conformant engines equally.
- ReactiveEvaluator API Update:
ReactiveEvaluatorconstructor now acceptsmeasure_bundleandcql_library_pathparameters, aligning with theMeasureEvaluatorAPI. - Interval JSON Handling: Fixed precision comparisons to correctly handle interval JSON in CQL temporal operations.
Bug Fixes
- CQL: Fixed interval JSON parsing in precision comparisons (affected CMS157 and related temporal tests).
- CQL: Prevented parser loop and enforced inline recursion limit for deeply nested expressions.
- CQL: Fixed
RolledOutIntervals— implemented alternative approach avoiding DuckDB correlated UNNEST limitation. - DQM: Fixed CMS157 test data — corrected measurement period alignment with encounter dates.
API Changes
ReactiveEvaluator.__init__: Parameters changed from(con, measure, adapter)to(con, measure_bundle, cql_library_path, adapter).- Version Bump: All
fhir4dspackages bumped to version0.0.5. - WASM Assets: Updated translator wheel for the 0.0.5 release series.
Upgrade
pip install fhir4ds-v2==0.0.5
Version 0.0.4
May 2026
Version 0.0.4 marks the 100% Compliance Milestone — every test suite now passes at 100%, totaling 2,821 tests across CQL, FHIRPath, ViewDefinition, and DQM.
Highlights
- 100% Spec Compliance: All test suites now pass at 100% — CQL (1,706/1,706), FHIRPath (935/935), ViewDefinition (134/134), and DQM (46/46 measures).
- CQL Gap Closure: Resolved remaining 2 CQL spec tests —
RolledOutIntervals(DuckDB correlated UNNEST workaround) andIntegerIntervalProperlyIncludedInNullBoundaries(spec ambiguity resolved). - DQM Full Pass Rate: All 46 QI-Core 2025 CMS eCQMs now pass. 4 measures have documented upstream test data accuracy gaps (CMS135, CMS145, CMS157, CMS1017) that affect all conformant engines equally.
- ReactiveEvaluator API Update:
ReactiveEvaluatorconstructor now acceptsmeasure_bundleandcql_library_pathparameters, aligning with theMeasureEvaluatorAPI. - Interval JSON Handling: Fixed precision comparisons to correctly handle interval JSON in CQL temporal operations.
Bug Fixes
- CQL: Fixed interval JSON parsing in precision comparisons (affected CMS157 and related temporal tests).
- CQL: Prevented parser loop and enforced inline recursion limit for deeply nested expressions.
- CQL: Fixed
RolledOutIntervals— implemented alternative approach avoiding DuckDB correlated UNNEST limitation. - DQM: Fixed CMS157 test data — corrected measurement period alignment with encounter dates.
API Changes
ReactiveEvaluator.__init__: Parameters changed from(con, measure, adapter)to(con, measure_bundle, cql_library_path, adapter).- Version Bump: All
fhir4dspackages bumped to version0.0.4. - WASM Assets: Updated translator wheel to
fhir4ds_v2-0.0.4-py3-none-any.whl.
Upgrade
pip install fhir4ds-v2==0.0.4
Version 0.0.3
April 2026
Version 0.0.3 introduces the Zero-ETL Source Adapter architecture, enabling CQL measures, FHIRPath queries, and ViewDefinitions to run directly against external data without copying it into DuckDB.
Highlights
- Zero-ETL Source Adapters: Run clinical logic directly against Parquet data lakes, PostgreSQL databases, and CSV files — no data movement, no PHI duplication.
- New API:
fhir4ds.attach(),fhir4ds.detach(), andcreate_connection(source=...)provide a uniform lifecycle for all data sources. - Schema Validation at Registration:
SchemaValidationErroris raised immediately atattach()time if the adapter's view doesn't conform — fail fast, not during measure evaluation. - Backward Compatibility:
ExistingTableSourceprovides the adapter interface over pre-loaded data. No breaking changes forFHIRDataLoaderusers.
New: Source Adapters
| Adapter | Purpose |
|---|---|
FileSystemSource | Parquet, NDJSON, Iceberg files — local or cloud (S3, Azure, GCS) |
PostgresSource | FHIR JSON stored in PostgreSQL columns |
ExistingTableSource | Wraps pre-loaded DuckDB tables in the adapter API |
CSVSource | Flat CSV files with user-defined SQL projection |
FileSystemSource
- Supports Parquet (default), NDJSON, JSON, and Iceberg formats.
- Cloud storage via
CloudCredentials(S3, Azure, GCS). - Hive partition pruning for large datasets.
- Incremental delta tracking via file mtime.
PostgresSource
- Attaches to Postgres via DuckDB's
postgresextension (read-only). PostgresTableMappingdefines column-to-schema mappings per table.- All identifiers quoted via
quote_identifier()— prevents SQL injection from user-supplied names. - Scope boundary: Requires FHIR JSON in a column. Relational-to-FHIR column mapping is out of scope.
ExistingTableSource
- Wraps any existing DuckDB table/view in the adapter API.
- Validates schema at registration time.
- Zero migration cost for current
FHIRDataLoaderusers.
CSVSource
- User provides a
projection_sqlwith a{source}placeholder. - Full control over how flat CSV columns map to FHIR JSON (via
json_object()).
New API
fhir4ds.attach(con, adapter)— Registers a source adapter on an existing connection.fhir4ds.detach(con, adapter)— Unregisters an adapter, dropping the view and cleaning up.fhir4ds.create_connection(source=adapter)— Mounts a source immediately on connection creation.SourceAdapterProtocol — Interface contract for third-party adapter implementations (register(),unregister()).SchemaValidationError— Raised at registration time if the adapter schema doesn't conform.validate_schema()— Validates theresourcesview against the required schema contract.quote_identifier()— Safely quotes identifiers to prevent SQL injection.CloudCredentials— Encapsulates DuckDB secret configuration for S3, Azure, and GCS.
Security
- Identifier Quoting:
PostgresSourceandExistingTableSourceusequote_identifier()to prevent SQL injection from user-supplied table and column names. - Scope Boundary:
PostgresSourcedocumentation clearly states it requires FHIR JSON in a column — preventing misuse as a generic relational mapper.
Known Limitations
PostgresSourcerequires FHIR JSON in a Postgres column — constructing FHIR JSON from arbitrary relational schemas is not supported in this release.CSVSourcedoes not support incremental delta tracking.FileSystemSourceincremental tracking is mtime-based and may produce false positives.- Iceberg format does not support incremental delta tracking.
Migration Guide
Existing FHIRDataLoader users have no breaking changes. To adopt the adapter pattern:
# Before (still works, no changes needed):
loader = FHIRDataLoader(con)
loader.load_directory('/data/fhir/')
# After (optional — adds uniform adapter API):
from fhir4ds.sources import ExistingTableSource
source = ExistingTableSource()
fhir4ds.attach(con, source)
Upgrade
pip install fhir4ds-v2==0.0.3
API Changes
- Version Bump: All
fhir4dspackages bumped to version0.0.3. - WASM Assets: Updated translator wheel to
fhir4ds_v2-0.0.3-py3-none-any.whl. - New Module:
fhir4ds.sources— exported from the top-levelfhir4dsnamespace.
Version 0.0.2
April 2026
Version 0.0.2 focuses on reaching full spec compliance, enhancing performance through architectural optimizations and a new C++ extension, and hardening security.
Highlights
- Near-Full Spec Conformance: Achieved 99.8% conformance across CQL, DQM, FHIRPath, and ViewDefinition test suites, resolving over 150 identified gaps.
- 69.5x Performance Boost: Evaluation speed has increased significantly due to a hybrid C++/Python execution model and optimized metadata caching.
- DuckDB v1.5.2 Integration: Fully stabilized on the latest DuckDB version, including optimized WASM builds for browser-side execution.
- Standardized Conformance Logging: A new unified logging framework provides detailed pass/fail reporting across all engine components.
Performance Improvements
- Registry Caching:
MeasureEvaluatornow caches FHIR schemas and profile registries, eliminating redundant 1.5MB allocations per evaluation call. - Audit Deduplication: Optimized "Full" audit mode to automatically deduplicate Cartesian product results generated by complex LEFT JOINs in retrieve CTEs.
- C++ Extension Parity: Reached 100% feature parity between the Python UDFs and the high-performance C++ extension, allowing for hybrid execution that combines C++ speed with Python's flexibility.
Security Fixes
- JSON Injection Remediation: Fixed critical JSON injection vulnerabilities in the C++ evaluator's
type()andwidth_string()functions. - Thread Safety: Added synchronization locks to singleton registries and cache stores (
profile_registry,fhir_loader,variable_store) to prevent race conditions in multi-threaded environments. - ReDoS Protection: Implemented guards on maximum regex lengths to prevent Regular Expression Denial of Service attacks in string manipulation logic.
Enhancements
CQL Translator
- Point-to-Interval Promotion: Added automatic promotion of point operands to degenerate intervals (e.g.,
[x, x]) forStartsSameandEndsSameoperators to ensure spec-compliant temporal comparisons. - Distinct List Aggregates: Added support for standard aggregates (
Sum,Min,Max,Avg) on distinct list literals. - Clinical UDF Macros: Externalized clinical logic into structured DuckDB macros for better maintainability.
FHIRPath Engine
- Cross-Namespace Equivalence: Updated
TypeInfoto correctly treat FHIR primitive types and their System equivalents as the same type per FHIRPath §5.1. - Conversion Function Flexibility: Support for both functional and member invocation forms for
convertsToXfunctions (e.g.,convertsToBoolean(v)andv.convertsToBoolean()). - Semantic Temporal Validation: Added strict validation for calendar dates and times, including month day limits and leap year checks.
DQM & ViewDefinition
- Enhanced Narratives: Improved narrative generation for population results when detailed evidence capture is disabled.
- ViewDef String Escaping: Updated the SQL generator to correctly handle backslashes and single quotes within FHIRPath strings in ViewDefinitions.
Infrastructure & Tooling
- Centralized Logging: Added a new unified logging framework that tracks pass rates and failure details across all subprojects.
- Build-Time Auto-Discovery: Improved the build system to auto-discover DuckDB versions and wheel names, ensuring smoother Pyodide package installations.
- Benchmarking Submodule: Added
tests/data/dqm-content-qicore-2026as a git submodule to provide a standard set of 2026 QI Core measures for benchmarking.
Bug Fixes
- CQL: Fixed circular definition handling (QA-019) which previously caused
RecursionErrorin complex libraries. - CQL: Fixed
Count(distinct(defRef))producing invalid SQL when referencing non-existent columns. - FHIRPath: Resolved a regression in
DateTime > Datecomparisons. - FHIRPath: Fixed type compatibility logic in equality operators to correctly return
emptyfor incompatible types per §6.1.1. - ViewDefinition: Fixed a regression in time boundary generation where an unnecessary 'T' prefix was occasionally added.
API Changes
- Version Bump: The
fhir4ds,fhir4ds.cql,fhir4ds.fhirpath, andfhir4ds.viewdefpackages have all been bumped to version0.0.2. - WASM Assets: Updated the required WASM assets; integrations must now use the
0.0.2translator wheel.
Version 0.0.1
Initial Release - Early 2026
The initial release established the foundation for the FHIR4DS engine.
- Unified Interface: Provided a single entry point for CQL, FHIRPath, and ViewDefinition execution.
- DuckDB Integration: Implemented the first set of Python-based UDFs for FHIR logic.
- Initial WASM Support: Demonstrated browser-side clinical reasoning using Pyodide and DuckDB-WASM.