Skip to content

Criteria Requirements Library Profile

Canonical../StructureDefinition/nexus-criteria-requirements
Statusdraft · 1.26.0
BaseLibrary (constraint)
SourceFSH · JSON

The data-requirements manifest generated for a compiled clinical criterion: a FHIR R4 Library with type = module-definition, declaring the resource types the logic retrieves, the profiles they must satisfy, the code and value-set filters applied, and the elements read. Derived from the compiled logic rather than authored beside it, so it cannot drift from the criteria it describes. A deployment artifact verified when a consuming host starts, not an API surface an application reaches.

Overview

A criteria requirements Library is the data-requirements manifest a compiled clinical criterion travels with. It says what data the logic reads: which resource types it retrieves, which profiles those retrieves were bound against, which code and value-set filters were applied, and which elements of the retrieved resources the logic actually touches.

It is derived from the compiled logic, never authored beside it. Translation and analysis happen once, when a criterion is written; this file is written at the same moment, from the same compiled tree. That is the whole reason to trust it -- it cannot disagree with the logic it describes, and a criteria library that also carried a hand-written dataRequirement would have two answers to one question with nothing to say which the logic obeys.

You do not need a CQL compiler to consume this

Reading a manifest is a JSON parse. The criteria artifacts page in the handbook walks the whole artifact set and the boundary between authoring time and serving time; the population page shows dataRequirement driving a query generator.

Why this shape is constrained and the other Library is not

This specification publishes two Library resources with nothing in common but the resource type, and only this one is profiled.

The reason is that this one has a consumer that refuses to run without it. A criteria pack is verified when a consuming host starts, and the host will not start on a manifest whose dataRequirement is empty, or on one carrying a codeFilter with no path. A criterion that declares it reads no data fires for everyone or for no one, and the artifact does not say which; a code filter with no path filters on nothing a consumer can determine. Both were refusals living in one service's startup path and stated nowhere a reader of this specification could find them. They are cardinality on this profile now, which is where a rule of that kind belongs.

The other is the CQL model definition, which is type = model-definition, carries its ModelInfo as an attachment, and has no dataRequirement at all. It is a publication wrapper: the compiler that uses that ModelInfo loads it as an XML file rather than as FHIR. One profile cannot describe both shapes, and the second has no consumer that a profile would help.

Nothing here is new work for a producer

Every constraint on this page was checked against the manifests a pack ships today, and each one already held on all of them. The generator cannot emit a Library that violates this profile: it refuses a criterion whose compiled logic carries no library identifier or version, and it throws rather than write a code filter whose path it could not resolve. This profile is a statement of what is already true, not a shape anyone has to migrate to.

The absences matter as much as the constraints. A shipped manifest carries no id and no meta.profile, and neither is required here. It is a file inside a pack read from disk, not a resource served from an endpoint -- it has no server identity to carry, and no reason to nominate its own profile. It likewise carries no identifier, no meta.source and no narrative. Requiring any of them would invalidate every manifest in circulation and buy nothing.

The two derived flags

Both extensions declare Library as their only context, and both are populated from the same analysis that produces dataRequirement.

criteria-relative-date is required, and required even when it is false. It answers whether membership in the criterion can change through the passage of time alone -- "no visit in the last six months" can, "two results ninety days apart" cannot -- and that decides whether a change feed is sufficient or a periodic sweep is also needed. If it were written only when true, an absent value would mean either the analysis ran and the answer is no or no analysis ran, and those are opposite instructions. A consumer reading absent-as-false would silently skip a sweep a time-anchored cohort needed, and the cohort would go stale with every surface still reporting success. Making it 1..1 here means a manifest that omits it is invalid rather than ambiguous.

criteria-elements-read repeats, one element path per occurrence, and is optional as a set: a criterion may read nothing beyond the code its retrieve is bound by. Where dataRequirement bounds a fetch, this bounds a projection. Two properties are easy to get wrong:

  • It is a lower bound. The analysis reads retrieves and property accesses and does not follow inference across included libraries, so a path being absent is not proof the logic never reads it.
  • The paths are flat across every resource type in the manifest and carry no type prefix. Sizing a per-resource projection means intersecting this list with the types in dataRequirement, not reading it straight through.

Not reachable over SMART, deliberately

This profile carries no smart-exposed declaration, so no SMART scope names it and no application reaches one of these through the FHIR API. That is a decision rather than an omission: a criteria pack is a deployment artifact. It ships with the software, it is verified when the host starts, and it is read from disk. It is not record content, and the server capability statement does not list it among the types a conformant endpoint offers.