What's New
This page summarizes the major changes in each release of FHIR4DS.
Version 0.0.17
September 2026
Version 0.0.17 ships the CQL Cleanroom — a fully browser-native CQL workbench built on the operations layer. Every capability runs client-side: Pyodide hosts the fhir4ds wheel for stateless operations (parse, translate, validate), DuckDB-WASM executes the translated SQL, and the TS executor emits schema:1 envelopes that are field-for-field identical to the CLI and MCP adapters. The conformance baseline holds at 2832/2832 (ViewDefinition 144, FHIRPath 935, CQL 1706, DQM 47).
Operations layer (shared core)
- New capabilities:
validate_resource(loader-identity validation — a resource that passes validation always loads cleanly) andresource_schema(FHIR R4 StructureDefinition-driven field metadata). translate_cqlgains an audit-mode enum (none/population/full),output_columnsaliasing, andpatient_idspushdown; results carrycolumn_typesCQL metadata.parse_cql(include_ast=True)exposes statement-level AST trees.- New
compare_evidencecapability: strict evidence-payload diff with moved/added/removed/flipped classifications per patient and population. - CLI
verify --evidence/--baselinewrites and compares evidence artifacts; MCP gainscompare_evidence_tool.
CQL Cleanroom (web/cql-cleanroom)
- Monaco CQL editor with live diagnostics (markers from structured
Diagnostics.location), parameter panel, and multi-library tabs with IndexedDB workspace persistence + zip export/import. - Evaluation, test, and evidence panes over DuckDB-WASM: typed result tables, SQL viewer, test harness with failure reasons, patient drill-in with audit evidence, and population Sankey flows.
- Evidence compare mode (baseline paste vs. current explain) and share links (LZ-compressed URL fragments, ≤100 KB, never contain datasets).
- Resource Builder: schema-driven FHIR resource forms (8 types + raw JSON fallback) with validate-before-add gating and no-silent-data-loss edit round-trips.
- Visual algorithm editor v1: graph → CQL emitter with a parse round-trip guard before applying to the library.
Parity & verification
- Three-way capability matrix: CLI == MCP == browser envelopes on the
shared fixture, for both
run_testsandcompare_evidence. - Macro-sync contract test keeps the browser SQL macro surface in lockstep
with the Python translator (
test_macro_sync.py).
Known limitations
- 21 deep-comparator SQL macros remain browser-gap allowlisted
(
BROWSER_MACRO_GAP_ALLOWLIST); the visual editor canvas is a beta seam over the JSON graph editor.
Version 0.0.16
September 2026
Version 0.0.16 is the CQL type system release. A complete, authoritative
CQL type-inference layer (TypeMapBuilder) now runs after translation and
attaches typed metadata (cql_type_ref) to every library definition, and the
$cql facade serializer flips to a metadata-first contract: declared
types drive FHIR Parameters serialization, with runtime shape inference only
as a silent fallback for Any or a logged rescue when known metadata would
fail. The conformance baseline holds at 2832/2832 (ViewDefinition 144,
FHIRPath 935, CQL 1706, DQM 47) and generated SQL is byte-identical to
0.0.15 across the 47-measure DQM corpus — this is a metadata-only release.
Type system
- New
fhir4ds/cql/types/typeref.pycanonicalCQLTypeRefrepresentation (List/Interval/Tuple generics) shared by the translator and the FHIR facade; legacy stub modules removed. TypeMapBuilder(fhir4ds/cql/translator/type_map.py) types 70.3% of the 1354 definitions in the DQM-47 corpus (952 non-Any); the remaining Any results are the documented gap backlog (Property/Query-heavy defines).- Uncertainty-returning operators (
AgeIn*,duration/difference betweenon imprecise operands) are deliberately typedAnyso runtime interval results serialize correctly.
Facade ($cql)
CQLResultMetadatafallback chain is nowcql_type_ref → cql_type → sql_result_type → Any.- Serializer trusts known metadata; rescue is failure-driven, recursive
per-level, and logs a WARNING naming both types when it fires. Long
values, empty-list/tuple extensions, and interval
partshapes are unchanged. - Rollback flag:
CQLServerConfig.metadata_first_serialization=Falserestores the 0.0.15 value-first reconcile verbatim.
Consolidation
- The legacy
_infer_cql_typeis now a thin wrapper over a verbatim compatibility port (byte-exactness proven by a 1049-define snapshot diff); two duplicated helpers were deleted and their callers now sharetype_mapmodule functions; a CI drift tripwire pins builder-vs-legacy equivalence on a shared corpus.
Version 0.0.15
September 2026
Version 0.0.15 is the DuckDB 1.5.5 reliability release. The embedded engine is upgraded from DuckDB 1.5.2 to 1.5.5 (native and WebAssembly binaries rebuilt and redeployed in lockstep), and a full 36-iteration QA campaign across all twelve product domains hardened the FHIRPath engine, the CQL translator, ingestion, and the terminology surface. The conformance baseline holds at 2832/2832 (ViewDefinition 144, FHIRPath 935, CQL 1706, DQM 47).
Platform
- DuckDB upgraded 1.5.2 → 1.5.5 (wheel pin, native extensions,
duckdb-wasm 1.33.1-dev64.0, submodule trees). Cloud credential options
realigned to the DuckDB 1.5.x secret surface: S3/Azure/GCS snake_case
aliases map to native option names, Azure service principals emit
PROVIDER service_principal, and options removed upstream (account_key,service_account_json) now raise actionable errors.
FHIRPath engine (24 fixes, QA-001..QA-008)
- Native/fallback parity: Decimal-typed
0/1booleans, empty-expression row resilience, metadata-gated temporal+concatenation, JSON cross-kind equality (object/array vs scalar → empty), minute-precision DateTime ± minutes arithmetic, temporal typing of arithmetic results ((@2016-02-29 - 1 month) > 'abc'is now empty), §4.4.1 empty propagation precedence in('a'|'b') / {}, and singleton-violation ordering forin/contains.
CQL translator (QA-009..QA-021)
- Dynamic FHIR interval
union, bareexpand X.period per dayparsing, stored-listexpand/collapsedefines (Count/Firstconsumers), query aggregates over retrieves (patient-correlated folds), braced{ <query> }list selectors in every consumer, chainedwithclauses (CMS71-style),{ <query> }as query source, audit-modecontainsover multi-valued properties, and auditCount(...) >= Nevidence fan-out. evaluate_measureoutput-columns and retrieve type validation now fail typed and actionable (ValueError/TranslationError) instead of leaking DuckDB CatalogExceptions.
Terminology (medterm4ds)
AutoCoderConfig.top_kvalidated at construction; autocoding extension roundtrip and closure-table surfaces verified end-to-end.
Version 0.0.14
September 2026
Version 0.0.14 is the WASM C++ parity release. Ten translator-reachable CQL functions that previously existed only as Python UDFs now ship in the native C++ DuckDB extension, closing the last gaps between the desktop runtime and the no-Python browser (WebAssembly) runtime. The conformance baseline holds at 2832/2832 (ViewDefinition 144, FHIRPath 935, CQL 1706, DQM 47).
WASM C++ parity
- Ported to the C++ extension:
cqlDivide(exact scale-8 half-up decimal division),CQLMessage,coding_matches/coding_matches_exact,fhirpath_in_valueset,cqlChildren/cqlDescendants(with CQL-05 transport markers),cqlDateTimeAdd,ratioCompare, andConceptToListCode. Every port is differential-tested against the Python authority (3,000+ randomizedcqlDividecases, 1,200 coding-match cases, 800 structural-traversal cases — zero divergences on the conformant input classes). - Three dead Python registrations removed (
ConvertQuantity,cqlDateTimeSubtract,cqlNormalizeTZ) and the between-family casing reconciled with the translator's emit spellings. cqlDateTimeAddandratioCompareremain Python-authoritative on desktop (documented divergent input classes); the C++ scalars serve the no-Python/WASM runtimes.- Both DuckDB extensions rebuilt for native and WASM; the browser demos
run identical binaries. The CQL playground gained an
exact-decimal-division end-to-end case (
10.0 / 3.0 → 3.33display), verified against the rebuilt WebAssembly — including the previously failing decimal division case.
Fixes
resolve()macro bind failure (latent since May): registering CQL macros shadowed DuckDB's built-intrim(x, chars), breaking any translated CQL usingresolve()in the standard registration flow. The macro body now usesregexp_replace, with regression coverage in both load orders.- Browser runtime: Arrow DECIMAL columns now render with their fractional part (unscaled-BigInt rescale), and the four type-disambiguation macros required by quantity comparisons are registered in both web apps.
Integration
- medterm4ds dependency bumped to 0.0.4 (
>=0.0.4,<0.0.5) — CDC CPT↔CVX crosswalk, annotation fields on all surfaces, and whitespace-code 400s. Verified against the 0.0.4 candidate (runtime frozen at the release commit).
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.