# Healthcare terminology: the same label can mean a different service

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:

```json
{
  "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.

## 3. Run the terminology lab

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.

```bash
python3 fde-healthcare-terminology.py
python3 fde-healthcare-terminology.py --json > terminology-guarded.json
python3 fde-healthcare-terminology.py --match-display --json > terminology-broken.json
```

Before 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](/training/guides/healthcare-eligibility) teaches how to interpret that response. Mapping alone establishes none of those eligibility facts. The earlier interpreter does not enforce terminology versions. Continue with the [connected healthcare lab](/training/guides/healthcare-handoff) to add that comparison around both unchanged interpreters and expose the defect when the response version is ignored.

## 5. Change the evidence yourself

Keep the original file, then create `terminology-challenge.py` beside it:

```python
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](/training/guides/financial-services-operations).

Official references checked 23 October 2026: [HL7 R4 Coding](https://hl7.org/fhir/R4/datatypes.html#Coding), [CodeSystem](https://hl7.org/fhir/R4/codesystem.html), [ValueSet](https://hl7.org/fhir/R4/valueset.html), [ConceptMap](https://hl7.org/fhir/R4/conceptmap.html) and [mapping field definitions](https://hl7.org/fhir/R4/conceptmap-definitions.html). The examples, lab, diagram and acceptance rules here are original teaching material.
