Free learning / 45-minute terminology lab
Healthcare terminology: the same label can mean a different service
Define Coding, CodeSystem, ValueSet and ConceptMap. Run fourteen synthetic mapping cases and prove why matching display text can change the business question.
No account needed. Use your own copy for writing and keep the original as a reference.
Engineering lab library / Run locally
Prove the meaning behind the label.
Predict fourteen mappings, reproduce two label-matching failures and inspect which evidence permits the next business question.
Real local Python over invented codes and maps. No network, clinical terminology or patient data; this is a narrow teaching contract, not a terminology server.
Start here / Python 3.11+ · Standard library
Healthcare terminology mapping lab
Inspect fourteen mappings, reproduce a false label match and preserve versions, direction and unresolved meaning.
Python 3.11+ · standard library only · invented FHIR R4 subset
A coordinator says, “Both systems call it a visit. Why can't we join them on that name?” As the forward deployed engineer, you need to explain the problem before proposing an agent or a matching algorithm. A familiar word can hide a different business concept. This workshop makes that problem visible, then gives you code you can run and challenge.
This is an original, synthetic FHIR R4 terminology exercise. All codes, organizations and URLs are invented. It uses no clinical terminology, patient record, account, model or network service. It prepares a service identity; it does not determine coverage, clinical suitability, authorization or payment.
1. Start with a qualified name, not a familiar word
Imagine two software packages each export a class named Client. The name alone does not tell you which implementation you have. You need the package and its version. Healthcare codes have a similar identity problem: a short code belongs to a particular coding system, and a version can matter to its meaning.
In this workshop the source is:
{
"system": "https://example.invalid/local-services",
"version": "local-1",
"code": "VISIT",
"display": "Visit"
}system identifies the vocabulary; code identifies a concept inside it; version identifies the vocabulary revision used here. display helps a person read it. Changing the display to “Consultation label” does not change this exercise's identity. Changing the code to ADMIN does, even if the screen still says “Visit”. These URLs are identifiers, not instructions to fetch data from the internet.
2. Separate the dictionary, the allowed set and the translation
| Term | Familiar technical analogy | What it contributes |
|---|---|---|
| Coding | A qualified symbol and version | One represented concept, with optional readable text. |
| CodeSystem | A named vocabulary | Defines or describes codes and their meanings. |
| ValueSet | Allowed choices for a particular field | Selects concepts from one or more coding systems for a context. |
| ConceptMap | A reviewed translation table | Records a directed relationship between source and target concepts. |
A ValueSet does not translate a code. A ConceptMap does not make every related concept interchangeable. A mapping may be broader, narrower or conditional; those differences can change the question you ask the receiving system. The R4 field used in this lab is equivalence. Other FHIR releases need their own version-specific adapter.
Our fictional agreement maps local-services | local-1 | VISIT to synthetic-services | payer-1 | SYNTHETIC-VISIT. The labels are different. The explicit mapping is the evidence. Reversing the arrow needs a separate reviewed agreement; it is not a dictionary lookup you can automatically invert.
The diagram follows this single business decision. Use each step to explain what information has been established and what remains unanswered.
UNDERSTAND THE SYSTEM
A shared label is not a shared identity
Follow a local service code into a different vocabulary. Establish the translation before asking what the patient's plan reports.
See what moves and why.
Read the connections in plain English
- 01Local service → Reviewed mapping
The display is not used to select a source entry.
- 02Reviewed mapping → Receiving vocabulary
Only the agreed direction and vocabulary versions apply.
- 03Receiving vocabulary → Resolve one target
Inspect the complete set of matching targets before selecting one.
- 04Workflow's allowed set → Resolve one target
A translated code must also belong to the agreed target set.
- 05Resolve one target → Next business question
Retain the selected map path and the still-unanswered eligibility question.
- 06Resolve one target → Next business question
The terminology steward resolves the gap before the workflow continues.
Check your understanding: A different code still displays ‘Visit’. Can the agent use the same mapping?
No. The lab's deliberately broken display matcher does exactly that and invents a translation for ADMIN. The guarded version matches the qualified code, preserves the gap and routes it to terminology review.
3. Run the terminology lab
HEALTHCARE TERMINOLOGY / COMPARE THE MEANING
Which identity does this map actually translate?
Compare the source with the map row, predict the result, then inspect what the Python lab recorded.
Recorded Python runs · Invented codes · No patient dataSame label. Different source code.
The source screen says Visit, but its code is ADMIN. The map's source row is VISIT and also displays Visit. Compare both identities before deciding whether the translation applies.
01 / SOURCE IDENTITY AND AVAILABLE MAP ROW
group[0].element[0] · 1 row in this map
| Field | Source supplied | Map expects |
|---|---|---|
| Coding systemSame | https://example.invalid/local-services | https://example.invalid/local-services |
| VersionSame | local-1 | local-1 |
| CodeDifferent | ADMIN | VISIT |
| Display textNot identity | Visit | Visit |
02 / WHAT THIS ROW DECLARES
https://example.invalid/synthetic-servicesTARGET 1 / group[0].element[0].target[0]
SYNTHETIC-VISIT
Office encounter
- Declared relationship
- equal
- Allowed by the workshop
- Yes, in the agreed target set
These are claims in the synthetic map. A matching row, an active flag or membership in the allowed set alone does not establish an accepted translation.
Inspect the exact source, map and agreement
{
"source": {
"system": "https://example.invalid/local-services",
"version": "local-1",
"code": "ADMIN",
"display": "Visit"
},
"concept_map": {
"resourceType": "ConceptMap",
"url": "https://example.invalid/maps/local-to-payer",
"version": "workshop-1",
"status": "active",
"group": [
{
"source": "https://example.invalid/local-services",
"sourceVersion": "local-1",
"target": "https://example.invalid/synthetic-services",
"targetVersion": "payer-1",
"element": [
{
"code": "VISIT",
"display": "Visit",
"target": [
{
"code": "SYNTHETIC-VISIT",
"display": "Office encounter",
"equivalence": "equal"
}
]
}
]
}
]
},
"contract": {
"map_url": "https://example.invalid/maps/local-to-payer",
"map_version": "workshop-1",
"source_system": "https://example.invalid/local-services",
"source_version": "local-1",
"target_system": "https://example.invalid/synthetic-services",
"target_version": "payer-1",
"allowed_targets": [
"SYNTHETIC-VISIT"
]
}
}Predict or inspect directly. No grade or completion is recorded.
In the online guide, start with the seven recorded cases in this section. Compare the source identity with the actual mapping row; switch between guarded and deliberately broken lookup for the two label cases. Predict the selected run, then reveal its exact recorded result and handoff. These are reproducible Python outputs, not browser execution or a scored assessment.
Download fde-healthcare-terminology.py and run it with Python 3.11 or newer. It uses only the standard library and writes reports only when you redirect output.
python3 fde-healthcare-terminology.py
python3 fde-healthcare-terminology.py --json > terminology-guarded.json
python3 fde-healthcare-terminology.py --match-display --json > terminology-broken.jsonBefore running, predict these two cases: a correct code with a renamed display, and a different code with the same display. In guarded mode the first maps and the second does not. In broken mode the outcomes reverse. Inspect source, concept_map and result together: the reports use identical inputs, so the changed comparison caused the difference.
The report includes fourteen cases:
| Case family | Evidence to inspect | Expected guarded behavior |
|---|---|---|
| Exact identity; renamed display | Source system, version and code | Map to the same qualified target. |
| Same label, different code; same code, different system | The actual qualified source | Withhold translation. |
| Missing source version; changed target version | Both vocabulary versions | Ask for the agreed context. |
| Unreviewed map version; retired map | Map identity and lifecycle | Stop before selecting a target. |
| Wider target; conditional map | Relationship and required context | Route to terminology review. |
| Duplicate mapping group | All matching targets, not the first | Refuse ambiguity. |
| Target outside the agreed set | Target allowed by this workflow | Withhold translation. |
| Unmapped default; reverse direction | Missing explicit forward mapping | Do not invent a fallback or reverse map. |
The lab deliberately requires explicit versions, one target, an accepted relationship and membership in a tiny agreed target list. That list models the result of an agreed terminology binding; this code does not implement ValueSet expansion or validation. Some valid FHIR maps are outside this narrow contract, including defaults and context-dependent mappings. Refusing them here does not make those representations invalid.
4. Inspect the evidence before continuing the workflow
The successful result contains a qualified target plus the exact selected path, such as group[0].element[0].target[0]. It records which map URL and version were used. An unresolved result has target: null and belongs to the terminology steward: the role responsible for settling this mapping, not an invented person or an available mentor service.
The static CONTRACT represents a separately reviewed agreement. A document claiming status: active is not organizational approval. Matching its URL and version is not a signature or proof of unchanged bytes. A real integration also needs controlled artifact provenance, applicable profile and binding validation, licensing where relevant, change review and an owner. The script is a teaching subset, not a terminology server or complete FHIR validator.
After mapping, eligibility operations can form a question with the intended patient, payer, coverage and service date. Lesson 104's eligibility workbook teaches how to interpret that response. Mapping alone establishes none of those eligibility facts. The earlier interpreter does not enforce terminology versions; connecting it to this adapter requires an explicit version-aware response contract, not simply copying a display string into a request.
5. Change the evidence yourself
Keep the original file, then create terminology-challenge.py beside it:
import runpy
lab = runpy.run_path("fde-healthcare-terminology.py")
source = lab["coding"]()
mapping = lab["concept_map"]()
target = mapping["group"][0]["element"][0]["target"][0]
target["equivalence"] = "narrower"
target["comment"] = "Synthetic example: this target adds a setting restriction."
print(lab["translate"](source, mapping)["reason"])Predict relationship_not_accepted, then run the challenge. Explain the meaning change before trying to repair it. Changing the word back to equal makes the code pass, but it supplies no evidence that the concepts are equal. A real repair requires the terminology owner's decision and updated acceptance cases.
Now remove display from the original source. Predict and prove that guarded matching still works. Add a second matching target in another group; demonstrate why choosing array index zero hides ambiguity. Finally change the source version while retaining its code and label. Write down why that change needs review rather than a fuzzy search.
Keep the input, prediction, observed reason, selected evidence path and proposed next action for each experiment. Exit code zero means the report ran, not that you passed an assessment or proved a business outcome.
6. Rehearse the handoff and keep your proof
Give a peer or facilitator one minute to change a label, version or relationship without telling you which. Explain the result in plain language before showing JSON. If working alone, label the exercise self-review. No live mentorship or credential is implied.
For a supported translation, your handoff might say: “The reviewed workshop map resolves the local VISIT code to SYNTHETIC-VISIT in payer-1. Here is the selected target path. Eligibility operations still needs a correctly scoped response before saying anything about coverage or requirements.”
For a wider target, say: “This target covers more than the source concept. We have not agreed to substitute it. The terminology steward needs to settle the mapping before we ask the receiving system.” Do not say the service is denied: a mapping gap is not a coverage decision.
Keep your four-term explanation, guarded/broken comparison, three changed-input cases and both handoffs. Carry them into the protected healthcare receiving review. For a different domain's version of this problem, continue with financial-services business meaning.
Official references checked 23 October 2026: HL7 R4 Coding, CodeSystem, ValueSet, ConceptMap and mapping field definitions. The examples, lab, diagram and acceptance rules here are original teaching material.