12a. Which identifier routes what

The four identifiers (node_id, endpoint_id, system_id, creating_system_id) are defined in § The four identifiers. This section is the normative part: which one governs which request. Getting it wrong produces the worst class of bug in this architecture, a follow-up write delivered to the wrong CDR, and that bug succeeds silently.

12a.1 Routing rules (normative)

  • A follow-up read of a specific VERSION MUST be routed on creating_system_id first, then endpoint_id, then ask-all (§12.3, N22). Reading the originating copy is the intended behaviour, because that copy is the authoritative one.

  • A versioned write MUST be routed to the CDR that controls the target object. Control is established by system_id == creating_system_id of the target version - i.e. the CDR where the version was created, not merely a CDR that holds a copy of it (§12.4, N23, and the imported-copy hazard in §10.3).

  • An EHR-scoped request ({base}/v1/ehr/{ehr_id}/…) MUST be routed on the ehr_id → node binding established during resolution (§5.2) or carried explicitly by the client (§12.5) - not on creating_system_id, which describes versions, not EHRs.

  • A fan-out query is dispatched per endpoint_id (§8), and every contributing endpoint MUST be reported in meta.federation.endpoints[] under that same identifier (§9.5).

  • A result row that will be used for follow-up SHOULD carry both endpoint_id (where the row came from) and the uid (which carries creating_system_id). They answer different questions: endpoint_id says who told me, creating_system_id says who owns it. When they disagree, the row is a copy - see §10.3.

  • node_id, endpoint_id and system_id MUST be distinct namespaces. A gateway MUST NOT accept a system_id where an endpoint_id is expected (or vice-versa) merely because the strings happen to coincide, and the registry MUST be able to answer each lookup unambiguously. (N32.)

12a.2 Summary table for implementers

Question node_id endpoint_id system_id creating_system_id

Where do I send this fan-out query?

-

✔

-

-

Which node contributed this row?

✔ (via endpoint)

✔

✔

-

Where do I read this VERSION from?

-

fallback

via registry

✔

Where do I commit a new version of this object?

-

-

✔ (must equal)

✔ (must equal)

Where do I send {base}/v1/ehr/{ehr_id}/…?

-

✔ (from the ehr_id binding)

-

-

Who is accountable / audited?

✔

-

-

-

Who is admitted to the federation?

✔

-

-

-