rh-inf-cql
First-class CQL (Clinical Quality Language) authoring, review, debugging, and test-plan skill for the rh-skills informatics workflow.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
First-class CQL (Clinical Quality Language) authoring, review, debugging, and test-plan skill for the rh-skills informatics workflow.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Reviewer-gated extraction skill for deriving L2 structured artifacts from ingested normalized sources. Runs MCP terminology enrichment, presents batch proposals for human review, records decisions via concept review CLI, and writes finalized `topics/<topic>/structured/concepts/concepts.yaml` plus an extract plan that includes an explicit `concepts` terminology artifact row. Supported modes: plan · implement · verify. Use when the user asks to extract structured artifacts from sources for a topic.
Reviewer-gated formalization skill for converging approved L2 structured artifacts into L3 FHIR computable resources. Uses type-specific strategies to map each L2 artifact type to its correct FHIR R4 targets. Modes: plan, implement, verify
Source preparation skill for the HI evidence pipeline. Normalizes all files in sources/ to Markdown, infers and initializes topics, classifies each source (using discovery-plan.yaml as optional enrichment when present), and annotates with concept metadata in normalized front matter for downstream extraction. Modes: plan, implement, verify
Interactive conflict resolution guide for RH lifecycle plans. Iterates through all open concerns across extract-plan.yaml and formalize-plan.yaml, presents each to the human reviewer, records the resolution, and confirms the plan is clear before proceeding to implementation.
Unified topic-level verification orchestrator for the RH lifecycle. Read-only. Launches stage-specific verify workflows via subagents and returns one consolidated report. Modes: verify.
Use SNOMED CT's semantic attribute relationships to answer clinical questions. Finds concepts by relationship attribute (finding site, causative agent, associated morphology, procedure site), navigates the IS-A hierarchy, and composes property-filtered ValueSets. Use when the user asks things like "all disorders of the heart", "all procedures on the kidney", "all conditions caused by bacteria", "subtypes of hypertension", "symptoms of X", "complications of X", or any query that involves clinical relationships between concepts rather than simple text search.
| name | rh-inf-cql |
| description | First-class CQL (Clinical Quality Language) authoring, review, debugging, and test-plan skill for the rh-skills informatics workflow. |
| compatibility | Requires rh-skills project with topics/<topic>/computable/ structure and `rh` CLI on PATH |
| applyTo | **/*.cql, **/*.xml, **/Library-*.json, **/Measure-*.json, **/PlanDefinition-*.json, **/ActivityDefinition-*.json, **/tests/cql/**/*.json, **/tests/cql/**/*.yaml, **/skills/.curated/rh-inf-cql/** |
| metadata | {"author":"rh-skills","version":"1.1.0"} |
$ARGUMENTS
Read the user input and determine the operating mode (author, review, debug,
or test-plan). If no mode is stated, infer from context:
author.cql file + "review" / "check" / "audit" → reviewdebugtest-planIf mode is still ambiguous, ask the user to confirm before proceeding.
CONFLICTS: Any decision that could produce incorrect or ambiguous output MUST be confirmed by the human before proceeding. Do not resolve conflicts silently.
Before producing any output:
rh CLI binary is reachable (via RH_CLI_PATH, .rh-skills.toml [cql] rh_cli_path, or rh on PATH). If absent, halt and show cargo install rh hint.topics/<topic>/ exists. If it does not, halt and prompt the user to run rh-skills init <topic> or correct the topic name.topics/<topic>/structured/<artifact>.yaml..cql source file exists at topics/<topic>/computable/<LibraryName>.cql.## Critical Authoring Patterns). Only call reasonhub-search_spec_content (source: cql) if the specific pattern is not already covered there.Author mode — prohibited diagnostic commands: Do not run ls, git status, git diff, or rg --files as part of the authoring workflow. The directory structure is confirmed by steps 1–4 above. Any exec call not in the author workflow steps below is wasted work.
If any check fails, report the missing resource and halt. Do NOT proceed with a partial context.
rh-skills cql validate), compilation (rh-skills cql translate), and test execution (rh-skills cql test) are always delegated to the rh-skills CLI. The agent reasons about CQL but does not replace the CLI for deterministic operations.rh-inf-cql owns .cql source files and fixture cases. FHIR JSON packaging is outside scope.rh cql compile does not inject FHIRHelpers wrapper calls. Type coercion between FHIR and CQL system types is the runtime's responsibility, not the author's. Authors should still include fhir.cqf.common.FHIRHelpers for explicit conversions where needed.NEVER read the
rhRust source or therh-skillsPython source.
rh and rh-skills are black-box CLIs. The agent must not read, search, or
inspect their implementation source files under any circumstances — not to
understand behavior, not to debug errors, not to confirm flag syntax.
Prohibited actions (hard stop — do not proceed):
~/projects/rh/ (Rust crates, apps/rh-cli/src/, etc.)rh-skills install path (Python .py source)find, rg, grep, or cat against *.rs filespython -c "import rh_skills; ..." to locate and then read the sourceAllowed alternatives:
rh cql --help / rh cql eval --help for flag referencerh-skills cql --help for wrapper command reference.agents/skills/rh-inf-cql/ for runtime behaviorRuntime defaults (assume these unless the user specifies otherwise):
1.5.3 | FHIR model: 4.0.1 | Translator: standard defaults (signatureLevel none, enableAnnotations false)rh — does NOT auto-inject FHIRHelpers; fixture tests are executed through rh-skills cql test / rh cql evalParameter-only decision-table libraries are scaffold artifacts and are not acceptable finished authoring outputs.
Anti-patterns that cause silent failures or runtime errors:
| ❌ Wrong | ✓ Correct | Why |
|---|---|---|
M.authoredOn during Interval<DateTime> | ToDate(M.authoredOn) in Interval<Date> | FHIR dateTime strings silently return false in DateTime intervals |
date from M.authoredOn | ToDate(M.authoredOn) | date from runtime-errors on FHIR strings |
V.expansion.contains E where E.code = 'X' | C.code in "ValueSetName" | Manual expansion is unnecessary; engine resolves by name |
C.clinicalStatus = 'active' | C.clinicalStatus.value in { 'active' } | FHIR CodeableConcept — compare .value string |
define function "F"(p Interval<DateTime>): ... p ... | define "F": Interval[ToDate(start of ...), ToDate(end of ...)] | Typed function parameters with complex types (Interval<>, FHIR.*) fail to resolve in the rh translator; use named define expressions instead |
[Condition] C where C.recordedDate is not null | [Condition: "BellsPalsyValueSet"] C | Retrieve without a code or valueset filter returns ALL records of that resource type — always scope at the retrieve |
[Condition] C where exists(C.code.coding Coding where Coding.system = 'http://hl7.org/fhir/sid/icd-10-cm' and Coding.code = 'G51.0') | [Condition: "BellsPalsyValueSet"] C | Inline code-system matching is brittle, misses synonymous codes across systems, and bypasses the terminology pipeline — pre-coordinate a multi-system valueset and use retrieve-level scoping |
Do not read secondary docs files (authoring-guidelines.md, engine-notes/README.md, translator-options/README.md, cli/usage.md, etc.) before writing CQL. The information above and the anti-pattern catalog (search for Anti-pattern catalog in this file) covers the critical cases. Read those files only if a specific gap arises.
This skill turns the agent into a disciplined reviewer and test-oriented author for CQL artifacts. Use it for:
rh CLI evaluatorThe skill should prefer deterministic reasoning over stylistic improvisation. For detailed conventions, see:
skills/.curated/rh-inf-cql/docs/authoring-guidelines.mdskills/.curated/rh-inf-cql/docs/review-checklist.mdskills/.curated/rh-inf-cql/docs/testing-strategy.mdskills/.curated/rh-inf-cql/docs/terminology-policy.mdskills/.curated/rh-inf-cql/docs/runtime-assumptions.mddocs/authoring-guidelines.mdDo not optimize for: cleverness, compressing logic into dense one-liners, or vague positive review language such as "looks good."
Before making any recommendation, gather as much of the following as available. State clearly which items are missing and the likely impact of each gap.
context/runtime/translator-options/README.md only if non-default options are in use)rh engine — see context/runtime/engine-notes/README.md only if a non-default engine is in use)For any non-trivial request, follow this order. Do not skip to code edits unless the user explicitly asks for a narrow syntax-only change.
reasonhub-search_spec_content (source: cql) before writing any expression whose behavior is ambiguous. Prefer spec evidence over recall.rh-skills cql validate and rh-skills cql translate.rh-skills cql test against existing fixtures; identify gaps.For a given CQL library:
Output format: use the structured template from prompts/summarize-library.md.
When reviewing CQL, check all items in the Review Checklist below. For each
deficiency, produce a finding classified as BLOCKING, ADVISORY, or INFO
with:
Output format: use the report template from prompts/review-library.md.
When a translation or runtime error occurs:
Output format: use the template from prompts/explain-failure.md and then
prompts/propose-minimal-fix.md.
For each important definition, generate at minimum:
| Case type | What it proves |
|---|---|
| Positive | Nominal true / expected-result path |
| Negative | Nominal false / contrasting result |
| Null / missing-data | Absent resource, missing date, incomplete evidence |
| Boundary | Just below / exactly at / just above a threshold |
| Conflicting evidence | Multiple facts that might cause ambiguity |
| Terminology | In-valueset / out-of-valueset / version-drift behavior |
| Multi-event | Earliest, latest, first, or any-match semantics |
Prefer compact fixture sets that isolate one semantic point at a time.
Output format: use prompts/generate-test-scenarios.md.
When CQL is embedded or referenced from FHIR artifacts:
Apply every time unless the user asks for something narrower. See
docs/review-checklist.md for the full structured rubric.
When the rh CLI is available, use this loop:
rh-skills cql translate <topic> <library>rh-skills cql test <topic> <library>tests/cql/<LibraryName>/.If per-expression output is needed for debugging, run the evaluator directly:
rh cql eval topics/<topic>/computable/<LibraryName>.cql "<DefineName>" \
--data tests/cql/<LibraryName>/<case>/input/bundle.json
See context/runtime/cli/usage.md for full CLI reference.
Use these categories when classifying issues in reviews or debug reports:
| Category | Description | Fix domain |
|---|---|---|
syntax | Parse error, invalid token, grammar violation | Authoring |
translation | ELM generation failure, type inference error | Authoring |
type-mismatch | Operator applied to incompatible types | Authoring |
null-propagation | Unexpected null from missing optional element | Authoring |
interval-boundary | Inclusive/exclusive boundary produces wrong result | Authoring |
temporal-precision | Date/time comparison with mismatched precision | Authoring |
terminology-resolution | Code not in valueset, wrong system URL | Authoring |
retrieve-scope | Retrieve too broad; filtered too late downstream | Authoring |
unit-conversion | Quantity comparison without unit normalization | Authoring |
version-drift | Library, model, or valueset version changed | Authoring |
fixture-or-data-shape | Input bundle does not match model expectations | Fixture |
packaging | Library resource references, compiler options mismatch | Packaging |
model-mismatch | Wrong FHIR version, QI-Core vs base FHIR | Environment |
engine-behavior | Evaluator-specific handling of edge cases | Environment |
missing-binary | rh not on PATH or RH_CLI_PATH unset | Environment |
For all non-trivial responses, prefer this structure:
State the effective environment and assumptions (model, FHIR version, translator options, runtime, terminology versions). Be explicit about what is missing.
List the most important correctness or maintainability findings first. Classify
each as BLOCKING, ADVISORY, or INFO.
Suggest the smallest changes that address each finding. Show before/after for any CQL edit. Explain the semantic impact, not just textual change.
List the new or updated test cases required. Include case name, case type, expected outcome, and what semantic point the case isolates.
State explicitly what cannot be confirmed from current context — missing runtime details, unknown terminology expansions, unverified fixture assumptions.
Goal: Produce a valid, well-formed CQL library from L2 structured artifacts.
topics/<topic>/structured/<artifact>.yamlRead the structured artifact — extract:
library identifierdefine namesdefine per condition (PascalCase, no spaces)Valueset sourcing rule: Every valueset referenced in the CQL library must
be backed by a ValueSet FHIR resource in topics/<topic>/computable/.
The terminology L2 artifacts (topics/<topic>/structured/*.yaml with
artifact_type: terminology) are the authoritative control files that drive
this — each one formalizes into a ValueSet-<id>.json via
rh-skills formalize <topic> <terminology-artifact>.
Valuesets must be built before the CQL phase. The required concepts are known at extract time from the terminology L2 artifacts — do not wait until CQL authoring to discover missing valuesets.
Before authoring CQL:
structured/ for any
artifact_type: terminology files.computable/ValueSet-<id>.json. If not, run
rh-skills formalize <topic> <terminology-artifact> first.reasonhub-search_snomed, reasonhub-search_icd10, reasonhub-search_rxnorm,
reasonhub-search_loinc) to find semantically similar codes across systems.
Real-world data uses multiple coding systems and synonymous codes — a
valueset with only one code will produce false negatives in production.🔖 Future: Revisit reusability — well-known public valuesets (e.g., from VSAC, HL7, or FHIR community IGs) should eventually be referenced by their canonical URL rather than duplicated locally. For now, local-first via the terminology L2 pipeline is the required path.
Apply the CQL style guide (see Style Guide section below) and the authoring rubric (see Authoring Rubric section below) before writing any code.
Draft the CQL library using the template for the artifact type:
Measure (artifact_type: measure):
/**
* Library: <LibraryName>
* Version: 1.0.0
* Description: <one-line description from artifact>
* Author: rh-inf-cql (generated from structured artifact)
* Date: <today>
*/
library <LibraryName> version '1.0.0'
using FHIR version '4.0.1'
include fhir.cqf.common.FHIRHelpers version '4.0.1' called FHIRHelpers
codesystem "<SystemName>": '<system-url>'
valueset "<ValuesetName>": '<valueset-url>' // version '<pinned-version>'
parameter "Measurement Period" Interval<DateTime>
default Interval[@2024-01-01, @2024-12-31]
context Patient
define "Initial Population":
<expression>
define "Denominator":
"Initial Population"
define "Numerator":
<expression>
Decision table (artifact_type: decision-table):
One define per condition row from sections.conditions. The define name is the
condition label converted to PascalCase (e.g., "Facial weakness present" →
"FacialWeaknessPresent"). The PlanDefinition stub generated by rh-skills formalize
references these exact names in its action[].condition[].expression fields.
Do not use Boolean placeholder parameters as stand-ins for unresolved clinical
evidence. Parameters such as parameter "QualityOfLifeBurdenDocumented" Boolean default false
are acceptable only for true runtime inputs like "Measurement Period" or an
externally supplied execution flag. They are not acceptable substitutes for
patient findings, observations, diagnoses, procedures, questionnaire scores,
or therapy history drawn from the guideline.
Instead:
For example:
[Condition: "ChronicRhinosinusitis"] C with active-status logic, not
parameter "HasCrsDiagnosis" Boolean[Observation: "QualityOfLife"] O plus score threshold TODOs, not
parameter "QualityOfLifeBurdenDocumented" Booleanparameter "PriorTherapyInsufficient" Boolean/**
* Library: <LibraryName>
* Version: 1.0.0
* Description: <one-line description from artifact>
* Author: rh-inf-cql (generated from structured artifact)
* Date: <today>
*/
library <LibraryName> version '1.0.0'
using FHIR version '4.0.1'
include fhir.cqf.common.FHIRHelpers version '4.0.1' called FHIRHelpers
codesystem "<SystemName>": '<system-url>'
valueset "<ValuesetName>": '<valueset-url>' // version '<pinned-version>'
context Patient
// One define per condition row — names must match PlanDefinition action expressions
define "<ConditionOneLabelPascalCase>":
/* TODO: implement condition logic */
define "<ConditionTwoLabelPascalCase>":
/* TODO: implement condition logic */
Check the library against the authoring rubric (all 10 areas) — see Authoring Rubric section.
Validate by calling the deterministic CLI command:
rh-skills cql validate <topic> <LibraryName>
Do not declare the library complete until rh-skills cql validate exits 0.
If it exits non-zero, read the error output and fix issues before retrying.
Validate failure protocol:
rh-skills cql translate as a proxy to confirm
the CQL is structurally sound (translate succeeds ⇒ logic is likely correct,
validate error may be a tool bug). Record the discrepancy and proceed with
the translate result. Do not make further speculative edits.skills/.curated/rh-inf-cql/context/) or ReasonHub MCP spec tools
(reasonhub-search_spec_content with source_id: "cql").FHIRHelpers for local testing:
If rh cql validate reports unresolved FHIR type identifiers and the project
does not have FHIRHelpers available, install the fhir.cqf.common package:
rh download package fhir.cqf.common 4.0.1
This is an external dependency — do not commit FHIRHelpers .cql files
into the topic's computable directory. FHIRHelpers is required only for
local validation; the runtime resolves it independently.
The .cql file is now ready. FHIR packaging (Library JSON wrapper, Measure
JSON) is outside rh-inf-cql's scope — hand off to whatever packaging step
is appropriate for the context.
.cql file at topics/<topic>/computable/<LibraryName>.cqlrh-skills cql validate with zero errorsGoal: Produce a structured Markdown review report classifying findings as
BLOCKING, ADVISORY, or INFO.
.cql file# CQL Review Report: <LibraryName>
**Reviewed**: <date>
**File**: `topics/<topic>/computable/<LibraryName>.cql`
**Reviewer**: rh-inf-cql (automated review)
## Summary
- BLOCKING: N
- ADVISORY: N
- INFO: N
## Findings
### BLOCKING: <Finding Category>
**Area**: <rubric area or high-risk pattern>
**Evidence**:
```cql
<quoted excerpt>
Issue: Recommended fix:
| Area | Status | Notes |
|---|---|---|
| Model declaration and version | ✓ PASS / ✗ FAIL | ... |
| ... (all 10 areas) |
| Pattern | Status | Notes |
|---|---|---|
| Unpinned terminology | ✓ PASS / ✗ FOUND | ... |
| ... (all 7 patterns) |
| Concern | Status | Notes |
|---|---|---|
| CQL source present | ✓ / ✗ | ... |
| ... |
### Output contract
- Review report at `topics/<topic>/process/reviews/<LibraryName>-review.md`
- All 10 rubric areas covered (no category omitted)
- All 7 high-risk patterns scanned
- Accepted by `rh-skills verify` as review evidence
---
## Mode: debug
**Goal**: Identify the root cause of a CQL error and propose a minimal corrective
change.
### Inputs (provide at least one)
- A `.cql` file path
- Translator error from `rh-skills cql validate`
- Failing fixture: `case-NNN/input/bundle.json` + `expected/expression-results.json`
\+ actual output from `rh cql eval`
- Runtime error description
### Workflow
1. **Classify the error type** using the taxonomy below.
2. **Locate the responsible `define`** — trace from the error message or failing
expression back to the source statement.
3. **Propose the minimal corrective change** — prefer one-line fixes over
restructuring.
### Error taxonomy
| Category | Description | Fix domain |
|----------|-------------|------------|
| Temporal precision | Date/time comparison with mismatched precision | Authoring |
| Null propagation | Unexpected null from missing optional element | Authoring |
| Terminology mismatch | Code not in valueset, wrong system URL | Authoring |
| Retrieve scope | Too broad a retrieve, filtered after the fact | Authoring |
| Unit conversion | Quantity comparison without normalization | Authoring |
| Version drift | Library or valueset version changed | Authoring |
| Context misuse | `Patient` context used where wrong | Authoring |
| Missing binary | `rh` not on PATH or CQL_TRANSLATOR_PATH unset | Environment |
| Model mismatch | Wrong FHIR version, QI-Core vs base FHIR | Environment |
| Translator option mismatch | Options differ between compile and evaluate | Environment |
### Diagnosis report format
```markdown
# CQL Debug Report: <LibraryName>
**Error input**: <translator / test / runtime>
## Root Cause
**Category**: <from taxonomy>
**Responsible define**: `<define-name>` at line N
**Evidence**: <error message or diff>
## Explanation
<one paragraph>
## Minimal Corrective Change
```cql
// Replace the current expression with:
<replacement expression>
<if authoring: fix by editing .cql> <if environment: fix by correcting tooling setup / config>
---
## Mode: test-plan
**Goal**: Enumerate all `define` statements and produce a test plan Markdown plus
structurally valid fixture skeletons.
### Inputs
- Path to an existing `.cql` file
- Topic and library name
### Workflow
1. Parse all non-context `define` statements from the CQL source.
2. For each `define`, determine applicable test families from the matrix below.
3. Write the test plan Markdown.
4. Write fixture skeleton files for each case.
### Test family matrix
| Dimension | Case variants |
|-----------|--------------|
| Age | below threshold / at threshold / above threshold |
| Timing | before boundary / on boundary / after boundary |
| Terminology | code matches valueset / code not in valueset / code absent |
| Value | value present / value absent / value null |
| Events | single event / multiple events / conflicting events |
**Minimum cases per define**: 4×N rule — for N `define` statements, generate at
minimum 4N fixture cases: one positive, one negative, one null/absent, one boundary.
### Fixture directory structure
tests/cql// ├── case-001-/ │ ├── input/ │ │ ├── patient.json # FHIR R4 Patient resource │ │ ├── bundle.json # FHIR R4 Bundle (transaction or collection) │ │ └── parameters.json # (optional) FHIR Parameters for overrides │ ├── expected/ │ │ └── expression-results.json # { "": , ... } │ └── notes.md # What this case proves, placeholder explanations ├── case-002-/ │ └── ...
`expression-results.json` format:
```json
{
"Initial Population": true,
"Denominator": true,
"Numerator": false,
"Patient Age": 45
}
# Test Plan: <LibraryName>
## Define Inventory
| Define | Purpose | Test families |
|--------|---------|--------------|
| <name> | <intent> | age, timing, terminology |
| ... | | |
## Case Summary
| Case | Define(s) | Family | Expected outcome |
|------|-----------|--------|-----------------|
| case-001-... | ... | positive | IsAdult = true |
| ... | | | |
## Fixture Notes
<any special data requirements>
topics/<topic>/process/test-plans/<LibraryName>-test-plan.mdtests/cql/<LibraryName>/case-NNN-<description>/notes.md files explain placeholder valuesThe following patterns indicate high risk regardless of mode. Flag them with the
category and classification shown. See docs/authoring-guidelines.md for
guidance on preferred alternatives.
| Pattern | Category | Classification |
|---|---|---|
| Unpinned valueset or code system version | terminology-resolution | BLOCKING |
Hidden timezone or precision assumption (Today(), Now() without explicit context) | temporal-precision | ADVISORY |
| Quantity comparison without unit normalization on both sides | unit-conversion | BLOCKING |
| Retrieve without code or valueset filter — returns ALL records of that resource type | retrieve-scope | BLOCKING |
Retrieve too broad — correct code/valueset filter present but where clause applied downstream instead of at the retrieve | retrieve-scope | ADVISORY |
| Duplicate logic instead of a named helper definition | Style | ADVISORY |
Ambiguous null handling — assuming null is false without explicit is null check | null-propagation | ADVISORY |
Dependence on implicit engine behavior not documented in context/runtime/ | engine-behavior | ADVISORY |
| Mixed FHIR version assumptions in included libraries | model-mismatch | BLOCKING |
Library version not declared or declared as 0.0.0 | version-drift | ADVISORY |
| ELM not re-generated after CQL change | packaging | ADVISORY |
rh CLI is available, run it before claiming a library is correct.Check every authored library against all 10 areas. Flag deficiencies in the review report.
| # | Area | What to check |
|---|---|---|
| 1 | Model declaration and version | using FHIR version '4.0.1' present and pinned |
| 2 | Included libraries and versions | All include statements have explicit version strings |
| 3 | Terminology declarations and version pinning | All valueset and codesystem declarations have pinned versions or OIDs |
| 4 | Top-level documentation and intent | Library has a doc comment block with name, version, description, date |
| 5 | Separation of retrieval logic from derived logic | Retrieve ([Condition], [Observation], etc.) kept in dedicated define; derivations reference those defines |
| 6 | Reuse of helper functions | Repeated logic extracted into named helpers; no copy-paste expressions |
| 7 | Null/empty semantics | Null propagation is explicit; lists checked with exists before access |
| 8 | Interval boundary behavior | Interval operators (during, starts, ends, overlaps) include correct boundary (open/closed) |
| 9 | Date/time precision assumptions | Date truncation (ToDate(), date from) is explicit; no silent precision coercion |
| 10 | Output shape and expected result types | Each define has a clear expected type (Boolean, List, Interval, etc.) documented in a comment |
Flag each pattern as BLOCKING (must fix before use) or ADVISORY (should fix).
| # | Pattern | Classification | What to look for |
|---|---|---|---|
| 1 | Unpinned terminology | BLOCKING | valueset "X": 'urn:oid:...' without version pinning where reproducibility matters |
| 2 | Hidden timezone/precision assumptions | ADVISORY | Today() or Now() without explicit context clock; date arithmetic without ToDate() |
| 3 | Quantity comparison without unit normalization | BLOCKING | obs.value > 5 'mg' where source unit may differ |
| 4 | Retrieve without code/valueset filter | BLOCKING | [Condition], [Observation], [MedicationRequest] etc. with no code or valueset at the retrieve — returns ALL records of that type regardless of clinical meaning |
| 5 | Duplicate logic instead of helper definitions | ADVISORY | Same expression repeated in 3+ defines without extraction |
| 6 | Ambiguous null handling | BLOCKING | if X then Y without else null where null branch matters; comparing null to a value without ~ |
| 7 | Dependence on implicit engine behavior | ADVISORY | Logic that relies on FHIRHelpers auto-injection, implicit conversions, or unspecified operator overloads |
LipidManagementLogic, PHQ9AssessmentLogicversion '1.0.0'LipidManagementLogic.cql → library LipidManagementLogiccodesystem declaration per system; reuse across the libraryValueSet resource
in topics/<topic>/computable/ValueSet-<id>.json — verify it exists before
finalizing the library. See the valueset sourcing rule in the author workflow.define per resource type retrieve; name it "<Resource> by <filter>"~ (equivalent) for concept comparisons, = for exact equalityexists ( ... ) before accessing list elementsInterval[start, end] with explicit closed brackets over implicitToDate() when comparing dates; use ToDateTime() for datetime comparisonsDate and DateTimeFixedClock / "Measurement Period" parameter for deterministic evaluation[Observation] O where O.status = 'final' (literal string; use code)if X is not null then X else default — prefer Coalesce(X, default)First([Condition]) without an ordering expression= instead of same day as or interval operatorsM.authoredOn during Interval<DateTime> — silently returns false for FHIR dateTime strings; use ToDate(M.authoredOn) with Interval<Date> insteaddate from M.authoredOn — runtime error when authoredOn is a FHIR string; use ToDate(M.authoredOn)V.expansion.contains E where E.system = ... and E.code = ...) — use code in "ValueSetName" insteadwhere clause (where Coding.system = 'http://...' and Coding.code = 'X') — pre-coordinate a valueset using ReasonHub MCP and use [Condition: "MyValueSet"] retrieve-level scoping instead; inline matching misses synonymous codes across systems and bypasses the terminology pipelinedefine function "F"(p Interval<DateTime>): ... — typed function parameters with Interval<> or FHIR.* types fail to compile; use a named define expression with inline logic insteadThese are the only commands that perform file writes or validation. The agent must call these — do not write files directly.
| Action | Command | Status |
|---|---|---|
| Validate CQL syntax and semantics | rh-skills cql validate <topic> <library> | ✓ active (rh cql validate) |
| Compile CQL to ELM JSON | rh-skills cql translate <topic> <library> | ✓ active (rh cql compile) |
| Run fixture-based test cases | rh-skills cql test <topic> <library> | ✓ active (rh cql eval per expected expression) |
rh-skills cql test discovers fixture cases under tests/cql/<Library>/case-*/,
runs rh cql eval for every expected expression, compares actual vs expected
values, and exits non-zero if any assertion fails.
| Tool | When to use |
|---|---|
reasonhub-search_loinc | Look up LOINC codes for observation concepts in the library |
reasonhub-search_snomed | Look up SNOMED codes for condition/procedure concepts |
reasonhub-search_rxnorm | Look up RxNorm codes for medication concepts |
reasonhub-codesystem_lookup | Get UCUM units for a LOINC code; verify code display name |
reasonhub-search_valuesets | Find existing ValueSets to reference |
Use these tools before writing any expression whose syntax, semantics, or operator behavior is uncertain. Do not rely on recall alone for CQL grammar or FHIR Clinical Reasoning rules.
| Tool | When to use |
|---|---|
reasonhub-search_spec_content with source_id: "cql" | Interval semantics, null propagation, operator precedence, date/time arithmetic, retrieve syntax, query clauses (where, let, return, sort), type coercion rules |
reasonhub-search_spec_content with source_id: "fhir-r4" | FHIR resource field definitions, data type semantics, search parameter behavior |
reasonhub-search_spec_content with source_id: "fhirpath" | FHIRPath expression semantics when used in Library criteria |
reasonhub-list_spec_sources | Discover available spec source IDs and versions |
reasonhub-get_spec_context | Retrieve a specific section by heading (e.g., source_id: "cql", heading: "Interval") |
Trigger conditions — call reasonhub-search_spec_content when the pattern is NOT already covered in the Critical Authoring Patterns table above, and when:
overlaps, during, before, after, closed/open boundaries)+ N days, start of, end of, precision qualifiers)exists, in, contains, ~, !~, or iswhere clause on a retrieve — especially multi-property conditionsdefine that uses if/then/else with possible null branchesrh-skills cql validate fails after two correction attempts, use
rh-skills cql translate as a proxy (see Validate failure protocol above),
then report the discrepancy and ask the user for guidance. Do not attempt
further speculative fixes, web searches, or workarounds (e.g., symlinking
FHIRHelpers from local paths).| Operation | Path | Command |
|---|---|---|
| Read structured artifact | topics/<topic>/structured/<artifact>.yaml | direct read |
| Write CQL source | topics/<topic>/computable/<Library>.cql | direct write |
| Write ELM JSON | topics/<topic>/computable/<Library>.json | via rh-skills cql translate |
| Write review report | topics/<topic>/process/reviews/<Library>-review.md | direct write |
| Write test plan | topics/<topic>/process/test-plans/<Library>-test-plan.md | direct write |
| Write fixture cases | tests/cql/<LibraryName>/case-NNN-<desc>/ | direct write |
rh-inf-cql owns CQL content — the .cql source text, its logical
correctness, and its fixture cases. FHIR JSON packaging (Library wrapper,
Measure, PlanDefinition) is outside scope and must not be written by this skill.