Criteria Requirements Library Profile¶
| Canonical | ../StructureDefinition/nexus-criteria-requirements |
|---|---|
| Status | draft · 1.26.0 |
| Base | Library (constraint) |
| Source | FSH · 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.