# ADR-004 — CancerIndex public identifiers Status: accepted (2026-09-08) ## Context Entities come from many sources with their own identifiers (NCIt codes, DOIDs, OncoTree codes, HGNC ids, NCT ids, PMIDs, CIViC ids, ChEMBL ids…). CancerIndex needs stable public identifiers that survive merges, renames and source changes, are safe in URLs and JSON, and never leak database internals (spec §6, §347). ## Decision Public identifiers have the form `CI--` where `NS` is one of the namespaces in `packages/shared/src/ids.ts` (`CAN`, `GENE`, `VAR`, `DRUG`, `TRIAL`, `PUB`, `BIO`, `STUDY`, `METRIC`, `SOURCE`, `ORG`, `TRT`, `ANAT`, `GEO`, `PROV`, `EDGE`, `RANK`) and `n` is a zero-padded integer of at least 8 digits. They are minted by `mintId(db, ns)` from per-namespace counters in `id_sequences` (atomic upsert-increment), are never reused and never re-numbered. Rules: 1. Database auto-increment integers (`bigserial` keys of aliases, observations, edges…) are internal and never exposed as entity references. The API resolver refuses bare integers except PMIDs. 2. Every upstream identifier is kept in a searchable column or in `*_codes` tables with its system and `match_type` — never only inside a JSON blob. 3. A merged entity keeps its id with `status = merged` and `merged_into`; the API follows the pointer so old links keep working. Deprecated entities keep their id and a `deprecated_reason`. 4. Slugs (`cancers.slug`, `drugs.slug`, `variants.slug`) are human-friendly aliases for URLs; they are unique but may change, and the `CI-*` id remains the canonical reference. 5. Ingest runs use `ING--YYYYMMDD-`; provenance rows get a `CI-PROV-*` public id only when exposed. ## Consequences - Identifiers are stable across re-ingestion: connectors look entities up by upstream code or alias and reuse the existing `CI-*` id; only genuinely new concepts mint new ids. - URLs are permanent: `/cancers/CI-CAN-00000364` and `/cancers/lung-adenocarcinoma` both resolve. - Sharding or re-numbering would break the contract; the namespace counter is a deliberate single point of coordination (one database, ADR-001).