Skip to content

Clinical criteria (CQL)

Clinical Quality Language is how this specification expresses clinical criteria: the population logic behind a report, a cohort, or a decision-support rule. One language, so a criterion written once means the same thing whether it is evaluated for a single patient at the point of care or for a whole panel in a report.

Criteria here are authored against this specification's model rather than base FHIR, so a retrieve carries a profile canonical and everything derived from it names the profiles you already implement. The CQL reference page is the authoring contract, including which model version to declare.

Four activities, not one

"Working with CQL" is four separate jobs, and conflating them is the usual mistake:

activity when it happens what it needs
1 Translate CQL to ELM authoring time a CQL translator
2 Analyse ELM for data requirements authoring time an ELM walker
3 Evaluate logic against patient data serving time an ELM evaluator
4 Read the resulting artifacts any time a JSON parser

The first two run once, when a criterion is written or saved, and their output is published. Activity 4 is what most consumers actually do — which is why you do not need a CQL compiler to consume clinical logic from this specification.

Criteria artifacts is the fuller treatment: what a compiled criterion consists of, why the manifest carries hashes, and what that boundary does not cover.

Which page you want

Two jobs bring people here.

  • "I have one patient and a rule — does it fire?" Go to Evaluating a criterion for one patient, which covers evaluating against a chart, the refusals you will meet, and compiling a criterion to the rule trigger a decision-support engine takes.
  • "I want to run criteria across a population." Go to Running criteria across a population, which covers generating a criteria pack once and driving a query or SQL generator from the data requirements it carries.

What this specification gives you

A generated CQL model definition. Library/nexus-cql-modelinfo publishes the ModelInfo generated from this specification's own profiles, so a criteria author fetches the model from the specification rather than reconstructing it from the profiles.

Two extensions on the module-definition Library, both derived from the compiled logic rather than authored beside it, so neither can drift from the criteria it describes:

  • criteria-relative-date — whether membership can change through the passage of time alone. That decides whether the criterion needs a periodic sweep or a change feed is sufficient. It is always written, even when false.
  • criteria-elements-read — one element path per repetition, bounding what a projection has to materialise. A lower bound, not an exhaustive list.

A declared primary code path on the profiles where a bare code filter is meaningful, using HL7's cqf-modelInfo-primaryCodePath extension. Where a profile deliberately declares none, a bare code filter is refused rather than quietly matched against the wrong element; the CQL reference page lists which profiles declare one and why the others do not.

Unit safety through a measurement catalog. A compiled rule trigger holds a bare number, so a threshold that carries a unit is checked against a catalog of what each code's values are reported in, and refused when it cannot be proved harmless. It is never converted: 55 mmol/mol becomes 5.5 % under UCUM and means 7.2 % in medicine.