Skip to content

The Shared Knowledge Layer — KB + KG Foundation ("the brain")

Date: 2026-06-03 · AI Foundation KB doc 01 · Owner: Director of Pharmacy Operations Scope: Architecture-grade design for the single shared knowledge layer that all Rx360 AI engines plug into — the curated Knowledge Base (KB) + the Knowledge Graph (KG) that grounds Balance Meter (fall-risk), Smart Scheduling, Medication-Input Intelligence, refill anticipation, and AI triage/routing. Companion docs: Smart_Scheduling/KB/04_AI_Architecture_Metrics.md (the RAG-over-KB + deterministic-safety-rail pattern we extend), Smart_Scheduling/KB/02_Drug_Forgiveness_Tolerance_Data.md (the seed curated KB), Product_Specs/Medication_Intelligence_Engine_PHASED_PLAN_2026-06-04.md (the medication-object contract every engine reads).

Reader's takeaway in one line: Build one pharmacist-curated, versioned, auditable knowledge layer — a property-graph Knowledge Graph for relationships (drug → class → FRID → interaction → member event) sitting next to a row-addressable curated KB for clinical facts (tolerance windows, Beers flags, food rules) — served to every engine through a single retrieval/contract API behind a deterministic safety rail, with knowledge shipped as data/config, not code, so a pharmacist can correct a fact at 6 million-user scale without a software release.

Wellness-lane guardrail (applies throughout): The KB/KG is the internal clinical IP. Member-facing engines emit reminders, confirmations, and wellness insights — never dosing or diagnosis. Every node/edge/row that touches a clinical decision carries a clinical-line flag; flagged knowledge is served verbatim from the curated KB or routed to a pharmacist, never synthesized by a model (extends 04_AI_Architecture_Metrics.md §2.4).


0 · Why a shared layer at all (the thesis)

Today each engine is tempted to build its own drug lookup: Scheduling needs cadence + tolerance; Balance Meter needs FRID/Beers/anticholinergic-burden flags; Med-Input needs identity + class; Refill needs days-supply + pattern; Triage needs severity + escalation rules. These are the same underlying entities (a drug, its class, its risks, the member taking it) queried five different ways. Rebuilding that five times means five drift paths, five audit surfaces, five places a pharmacist correction has to land. The single most cited barrier in precision-medicine KG construction is exactly this: "existing approaches require expert review and curation; disease/drug representations lack consistency across repositories" — the PrimeKG team called harmonization-at-scale the dominant cost [1].

The fix is the pattern we already proved in Smart Scheduling: a curated KB behind a RAG/retrieval layer behind a deterministic rail [companion §2.2–2.4]. This doc generalizes that single-engine pattern into the shared foundation — adds the graph that connects the facts, and the contract that lets every engine read it without re-deriving it.

   ENGINES (consumers)         Scheduling   Balance Meter   Med-Input   Refill   Triage
                                    │            │             │          │        │
                                    └────────────┴──────┬──────┴──────────┴────────┘
                                                        ▼
   ┌──────────────────────────────  KNOWLEDGE LAYER API  ──────────────────────────────┐
   │  One contract: resolve(drug) · classOf · risks(FRID/Beers/ACB) · interactions ·    │
   │  toleranceWindow · foodTiming · pathsBetween · subscribe(knowledge-change)         │
   │  ── every response carries {entryId, version, source, clinicalLineFlag} ──         │
   └───────────────┬───────────────────────────────────────────────┬───────────────────┘
                   ▼                                                 ▼
   ┌──────────────────────────────┐               ┌──────────────────────────────────────┐
   │  CURATED KB  (facts)          │   join keys   │  KNOWLEDGE GRAPH  (relationships)     │
   │  pharmacist-authored rows:    │◀────RXCUI────▶│  property graph; nodes+edges:         │
   │  tolerance windows, Beers,    │   class URIs  │  Drug─[IS_A]→Class─[IS_FRID]→Risk     │
   │  food rules, miss-policy ptrs │               │  Drug─[INTERACTS_WITH]→Drug           │
   │  versioned · effective-dated  │               │  Member─[TAKES]→Drug · ─[HAD]→Event   │
   │  · clinical-line flag · author │               │  anchored to RxNorm/RxClass/SNOMED/ATC│
   └──────────────────────────────┘               └──────────────────────────────────────┘
                   ▲                                                 ▲
                   └──────── ONTOLOGY / TERMINOLOGY SPINE ───────────┘
              RxNorm (RXCUI) · RxClass (ATC/MeSH/ENZYME) · SNOMED CT · ICD-10 · ATC

1 · Modeling the healthcare / drug Knowledge Graph

1.1 Entities (node types)

The graph models the clinically and behaviorally relevant entities — a deliberately tighter set than a discovery KG like PrimeKG's ten biological scales [1], scoped to a senior-wellness adherence + fall-risk product:

Node type What it is Anchored to Why we need it
Drug / Clinical Drug A prescribable product at the level a member takes it (ingredient + strength + form) RxNorm RXCUI / SCD / SBD [2][3] The spine; every med-object resolves here
Ingredient Active moiety (e.g., metformin) RxNorm IN/PIN Duplicate-therapy + interaction reasoning
Drug class Therapeutic/pharmacologic/MoA class RxClass (sources: ATC, MeSH, NDF-RT/MED-RT, FDA EPC, ENZYME) [4][5] Class-level rules (cadence, FRID, Beers) attach here, not per-drug
Condition / Indication Disease state SNOMED CT + ICD-10-CM [6] Indication/contraindication context, triage routing
Risk marker A clinical risk property: FRID, Beers PIM, anticholinergic-burden score, NTI, controlled-substance, LASA Curated, mapped to class/drug The "fall-risk drug" and "high-stakes" concepts the engines key off
Interaction A drug–drug / drug–food / drug–disease interaction with severity + mechanism Curated (DDInter-style) + DrugBank-style annotation [7][8] Triage + pharmacist-view flags
Forgiveness / tolerance profile PK/PD-derived tolerance tier + food/timing rule Curated KB row (see §2) Smart Scheduling's core input
Member A pilot/production user (PHI; access-controlled) Internal ID (FHIR Patient) The longitudinal subgraph; row-level data stays local per memory rules
Event A medication-input, confirmation, dismissal, fall-signal, med-change, refill, escalation Versioned event taxonomy [companion §4.3] The behavioral layer; what makes the graph live, not just a reference dataset

FRIDs as first-class nodes, not a hard-coded list. Fall-risk-increasing drugs are conventionally defined by ATC class and grouped (CNS-active, cardiovascular, other) [9][10][11]. Modeling FRID as a risk-marker node attached to RxClass classes means: (a) a new drug auto-inherits FRID status by its class membership; (b) the pharmacist edits one class→risk edge, not N drug rows; (c) Balance Meter's "is this med fall-risk?" is a one-hop traversal, deterministic and auditable. The 2023 AGS Beers Criteria and the anticholinergic-burden scales (ACB/ACSBC, ~642 drugs) [12][13] are modeled the same way — as risk-marker nodes with curated drug/class edges and a numeric burden weight.

1.2 Relations (edge types)

Edges are typed and carry properties (this is the core reason for a property graph — §1.4):

  • Drug ─IS_A→ Class · Class ─SUBCLASS_OF→ Class (RxClass/ATC hierarchy) [4][5]
  • Drug ─HAS_INGREDIENT→ Ingredient
  • Class ─CARRIES_RISK→ RiskMarker {marker: FRID|Beers-PIM|NTI|anticholinergic, weight, beersRecommendation, effectiveDate, kbEntryId}
  • Drug ─INTERACTS_WITH→ Drug {severity, mechanism, management, source, clinicalLineFlag} [7][8]
  • Drug ─HAS_TOLERANCE_PROFILE→ ForgivenessProfile {tier, foodRule, missPolicyPointer, kbEntryId, version}
  • Drug ─INDICATED_FOR / CONTRAINDICATED_FOR→ Condition (the relation type PrimeKG showed is the differentiator — it had 61,350 contraindication + 18,776 indication edges that other KGs lacked) [1]
  • Member ─TAKES→ Drug {since, provenance: self|imported|pharmacist-verified, confidence} (mirrors the med-object provenance model)
  • Member ─HAD_EVENT→ Event {type, timestamp, context}
  • Event ─AFFECTS→ Member|Drug (e.g., the cross-engine medication-change event that simultaneously tightens the Balance Meter watch-window and opens a scheduling-attention period — our patent delta, now a graph edge)

This last point is the payoff of one shared graph: the cross-engine "medication-change" event is a single edge that every engine sees, instead of a message each engine reimplements.

1.3 The ontology / terminology spine (anchor everything; invent nothing)

Every node binds to a public terminology so we never define our own drug identity and so we stay interoperable with NCPDP SCRIPT, FHIR, and Surescripts downstream:

  • RxNorm / RXCUI — canonical drug identity and normalization across naming systems; the join key between KB rows and KG nodes [2][3].
  • RxClass — the class backbone, federating ATC, MeSH, NDF-RT/MED-RT, FDA Established Pharmacologic Class, ENZYME into RxNorm members [4][5]. This is why we don't hand-build a class tree.
  • ATC (WHO) — the international class system FRID definitions are written against [9][10][11]; also the bridge for ex-US drugs (ties to the Scanner_Label international work).
  • SNOMED CT + ICD-10-CM — conditions/indications, and the codes CDS standards expect [6].
  • OpenFDA / DailyMed SPL — NDC, strength/form/route, official-label food/timing rules (the authoritative source the forgiveness KB must cross-check) [companion §5.3].

Lesson from the field — harmonization is the hard part, and there's a known playbook. PrimeKG had to collapse 22,205 disease concepts to 17,080 because "MONDO has 37 autism concepts, UMLS has 192, Orphanet has 6" — they resolved it by picking one primary ontology (MONDO), mapping cross-references, then using embedding clustering (ClinicalBERT, ≥0.98 similarity) with manual validation [1]. Our analog: pick RxNorm as primary for drugs and SNOMED CT for conditions, map everything else to them via RxClass/UMLS crosswalks, and keep a pharmacist in the validation loop for every merge — never auto-merge clinical identity on embedding similarity alone. SapBERT-style entity resolution at a 0.8 threshold is a candidate generator, not the decider [14].

1.4 Property graph vs RDF triple-store — the decision

Dimension Property graph (Neo4j, Amazon Neptune-PG, TigerGraph) RDF / triple-store (Neptune-RDF, GraphDB, Stardog)
Model Nodes + typed edges with properties on both Subject-predicate-object triples; edges have no native attributes
Our need Edges must carry {severity, weight, effectiveDate, kbEntryId, clinicalLineFlag} — native fit Reifying edge properties is awkward (needs blank nodes/RDF-star)
Traversal Pointer-chasing; node-centric; fast multi-hop ("drugs in member's list that share a FRID class") [15][16] SPARQL binds variables via joins; edge-centric; slower deep traversal [15][16]
Standards/semantics Pragmatic; openCypher/Gremlin; weaker formal inference W3C standard; OWL reasoning, SPARQL federation, formal semantics [15]
2025 AI fit Vendors now ship graph-native vector search + GraphRAG + GNN pipelines [16][17] Strong for cross-institution federation and standards-based publishing
Scale Neo4j: billions of nodes / trillions of edges, sharding + async read replicas; Neptune: 128 TiB, 15 read replicas, ms latency [18][19] Comparable read scale; Neptune single-writer caps ingestion throughput [16][18]

Decision: property graph for the operational layer. Our edges are attribute-rich and traversal-heavy (the exact RDF weak spot), our queries are multi-hop relationship questions, and the 2025 tooling (graph-native vectors for the RAG layer, GraphRAG) is property-graph-first [16][17]. Concretely: Amazon Neptune is the default if we want HIPAA-eligible, managed, and the option to also speak RDF/SPARQL later (it supports both models in one service) [16]; Neo4j if we want the richest graph-data-science + GraphRAG ecosystem and Cypher ergonomics [17][18]. Either way the contract (§4) hides the choice from engines. Where RDF still earns a place: the terminology spine itself (RxNorm/SNOMED/ATC crosswalks) is naturally RDF and can live in a triple-store or be imported as reference data — a pragmatic hybrid, which is the mainstream 2025 position (use each where it's strong) [15][16]. Note real precedent for property-graph in production healthcare: Novo Nordisk's StudyBuilder runs on Neo4j, navigating CDISC/SNOMED/UCUM standards with compliance + automation [16].


2 · The curated KB alongside the KG

The graph holds relationships; the curated KB holds the clinical facts a pharmacist authors and owns. They are separate stores joined on RXCUI/class URIs, for a deliberate reason: a fact must be a single addressable, versioned, signed row — not an emergent property of a model or a buried graph attribute you can't cite.

This is the direct generalization of our existing drug-forgiveness KB [companion 02_…Tolerance_Data.md]: that document is already a table of pharmacist-authored, sourced, sign-off-flagged rows (tolerance tier, food rule, high-stakes flag, per-class). We make that schema the template for all curated knowledge, not just forgiveness.

2.1 The curated-KB row schema (every entry, every domain)

{
  "entryId": "kb_forgiveness_amlodipine_v3",
  "domain": "forgiveness | beers | acb | interaction | food-timing | miss-policy | frid",
  "subject": { "type": "class | drug", "rxclass": "…", "rxcui": "197361" },
  "assertion": { "toleranceTier": "high", "foodRule": "with-or-without",
                 "missPolicyPointer": "policy_high_forgiveness_v2" },  // domain-specific payload
  "clinicalLineFlag": true,            // true → served verbatim or routed to pharmacist; NEVER model-synthesized
  "provenance": {
    "source": "DailyMed SPL / AGS Beers 2023 / pharmacist judgment",
    "sourceUrl": "https://dailymed.nlm.nih.gov/…",
    "author": "npi:…",                 // the pharmacist who wrote it
    "approver": "npi:…",               // clinical sign-off (≠ author)
    "effectiveDate": "2026-06-01",
    "supersedes": "kb_forgiveness_amlodipine_v2",
    "status": "approved | draft | retired"
  },
  "version": 3
}

Every field maps to a requirement already in our companion docs: clinicalLineFlag = the wellness-lane gate [companion §2.2]; provenance.{author,approver,effectiveDate} = "every entry carries source, author, version, effective date, clinical-line flag" [companion §2.2]; supersedes = the audit chain. Real precedents validate this shape: DDInter's interaction entries carry severity + mechanism + management + alternatives, curated by a hospital pharmacist team [7][8]; the AGS Beers Criteria are versioned clinical artifacts (2015 → 2019 → 2023) [12]. We are doing for our product what those did for the field — but with our seniors' formulations and our sign-off chain.

2.2 KB and KG join, cleanly

  • KB rows are keyed by RXCUI or RxClass URI → they attach to the same identifiers the graph nodes carry. A KG edge (Class ─CARRIES_RISK→ FRID) points at the kbEntryId that justifies it.
  • A retrieval answer is therefore both: the graph gives the path (this member's drug → its class → FRID), the KB gives the cited fact + version behind each hop.
  • Auditability requirement (carried from companion §2.2): every engine decision logs the {kbEntryId, version} it relied on, so a changed tolerance window can be replayed against affected members.

3 · Curation, versioning & governance — "knowledge as data, not code"

The defining principle: a pharmacist must be able to add, change, or retire a clinical fact without a software release. Knowledge is config/data; code is the engine that reads it. This is the established CDS direction — FHIR represents decision logic as data (PlanDefinition, Library, ActivityDefinition) applied at runtime via $apply, and terminology as CodeSystem/ValueSet/ConceptMap resources, not compiled rules [20][21][22]. OHDSI runs the same way at massive scale: >10M concepts across 136 vocabularies, refreshed quarterly as data, not code [23][24].

3.1 The knowledge lifecycle (authoring → deploy, no release)

 DRAFT ──▶ PHARMACIST AUTHOR ──▶ CLINICAL SIGN-OFF ──▶ STAGED ──▶ GATED/CANARY ──▶ ACTIVE
 (analyst)   (source+author)      (approver ≠ author)   (validate)  (ring rollout)   (versioned, effective-dated)
                                         │                                              │
                                         └──── clinical-line entries MUST pass here ─────┘
                          RETIRE ──▶ superseded row kept for replay/audit (never hard-deleted)
  1. Add / draft — analyst or pharmacist drafts a row (status draft); the existing forgiveness table's [SIGN-OFF]/[APPROX] flags are exactly this state [companion 02_… header].
  2. Author + source — a licensed pharmacist authors the final assertion with source + sourceUrl; no model writes clinical content [companion §3.2].
  3. Clinical sign-off — a different pharmacist (approver ≠ author) signs off. Mandatory for any clinicalLineFlag: true entry. This is the GMLP "multidisciplinary expertise across the lifecycle" principle [companion §3.2 refs 19].
  4. Version + effective-date — approval mints a new immutable version; supersedes links the chain. Like OHDSI/ATHENA semiannual + urgent releases [23][24] and AGS Beers' dated editions [12].
  5. Gated/canary deploy as data — the new version propagates to the retrieval layer for a small ring first, monitored, then ramped — no code deploy, mirroring the PCCP-style gated-deploy loop we already adopted [companion §3.3, §5].
  6. Retire — status flips to retired; the row is never hard-deleted (replay + audit). Don't retire support where the need persists [companion §4.1 de-escalation note].

3.2 Propagation without a code release

Because knowledge is data, an approved version reaches engines through the retrieval layer + a knowledge-change event, not a rebuild: - The retrieval cache invalidates the changed entryId; engines pulling that fact get the new version on next read. - A knowledge-change event on the bus (same bus as the cross-engine med-change event) lets an engine react (e.g., Scheduling recomputes tolerance windows for members on the affected class). - This is the literal meaning of "knowledge as config": the pharmacist's sign-off is the deploy.

3.3 Governance guardrails

  • Separation of duties: author ≠ approver; both NPI-signed, timestamped.
  • Clinical-line is the bright line: clinicalLineFlag: true entries are served verbatim or routed to a pharmacist — never paraphrased by an LLM (the RAG layer grounds, the rail enforces) [companion §2.4].
  • No autonomous knowledge creation: models may propose a candidate row (e.g., from a new SPL); a pharmacist must author + a second sign off before it's active. Extends the AI-learning safety rail (learn → validate → clinical sign-off → gated deploy) to knowledge, not just model weights.
  • Everything replayable: versioned rows + decision logs {kbEntryId, version} mean any past member-facing decision can be reconstructed for audit/regulator/incident.
  • PHI boundary: Member/Event subgraph is operational PHI — encrypted, access-controlled, row-level data stays local per memory rules; only Safe-Harbor-clean aggregate derivatives leave the boundary [companion §3.1].

4 · One layer, many engines — the contract

The whole point is that no engine rebuilds the knowledge. They call one API; the layer hides whether an answer came from the graph, the KB, or both. Every response is grounded (carries provenance) so the calling engine — and the safety rail — can trust and cite it.

4.1 The knowledge-layer API (contract sketch)

// Identity & class
resolve(input)            → { rxcui, ingredient, doseForm, route, strength, drugClasses[] }
classOf(rxcui)            → [ { rxclass, source:"ATC|MeSH|EPC", hierarchy[] } ]

// Risk (Balance Meter, Triage)
risks(rxcui|list)         → [ { marker:"FRID|Beers-PIM|NTI|anticholinergic|LASA",
                                weight, beersRecommendation, kbEntryId, version, source } ]
anticholinergicBurden(list) → { totalScore, perDrug[], scale:"ACB", kbEntryId }

// Interactions (Triage, pharmacist view)
interactions(list)        → [ { pair, severity, mechanism, management,
                                clinicalLineFlag:true, kbEntryId, version } ]

// Scheduling
toleranceProfile(rxcui)   → { tier:"high|moderate|low", foodRule, timing,
                              highStakes:bool, missPolicyPointer, kbEntryId, version }

// Graph reasoning (any engine)
pathsBetween(a, b)        → [ traversal paths w/ edge provenance ]
sharedClassRisk(memberMedList) → { fridCount, beersCount, drivers[] }   // Balance Meter one-call

// Live updates
subscribe("knowledge-change") → stream of { entryId, version, affectedClasses[] }
subscribe("medication-change") → cross-engine event (Scheduling ↔ Balance Meter)

Contract invariant (non-negotiable): every clinical fact in a response carries {kbEntryId, version, source, clinicalLineFlag}. An engine may never emit a member-facing clinical statement that lacks this envelope — the deterministic rail blocks ungrounded clinical content [companion §2.4]. This is the groundedness/citation-coverage metric (target 100%) made into an API guarantee [companion §4.2].

4.2 How each engine consumes the same layer

Engine Calls it uses Reads from
Med-Input Intelligence resolve, classOf, interactions (pharmacist-view flags) Spine + KG + KB; produces the structured med-object that becomes Member─TAKES→Drug edges
Smart Scheduling toleranceProfile, classOf Curated forgiveness KB (its existing input) — now via the shared contract, not a private copy
Balance Meter (fall-risk) risks, anticholinergicBurden, sharedClassRisk FRID/Beers/ACB risk-marker nodes + KB weights
Refill anticipation resolve, toleranceProfile (days-supply context) Med-object + KB
AI triage / routing interactions, risks, pathsBetween KG severity edges + KB clinical-line entries → escalate vs self-serve

The medication-object contract (Medication_Intelligence_Engine_PHASED_PLAN §6) is the write side of this: Med-Input produces one normalized object → it lands as graph edges (Member─TAKES→Drug, provenance-weighted) → every other engine reads it back through this API. One object in, one knowledge layer out, five engines served — that is the foundation and the moat.

4.3 Serving pattern: structured-first, GraphRAG as fallback

Carry the companion's retrieval discipline up to the shared layer [companion §2.2]: 1. Structured lookup first — "amlodipine's tolerance tier" is a deterministic KB row + graph edge, not a nearest-neighbor guess. 2. Graph traversal for relationship questions — "which of this member's meds share a FRID class" is one Cypher/Gremlin hop. 3. GraphRAG (semantic) only as fallback / for interface jobs — phrasing, summarization, parsing — and every clinical fact it surfaces still comes from a cited KB row, never model memory. GraphRAG is the 2025 pattern for relationship-aware, traceable retrieval (Microsoft GraphRAG, 2024; 90%+ accuracy on schema-bound queries where vector-only RAG fails) [25][26][27] — but in our lane it grounds, it doesn't decide.


5 · Real precedents — who built these, and the lessons

Precedent What it is Scale Lesson for us
PrimeKG (Harvard) Precision-medicine KG, 20 sources harmonized 129,375 nodes / 4.05M edges; 17,080 diseases; 10 node + 30 edge types [1] Harmonization is the cost. Pick one primary ontology, map the rest, keep a human in every merge. Its indication/contraindication edges (the relations other KGs lacked) are the differentiator — model relations, not just nodes [1].
Hetionet Drug-repurposing heterogeneous network 47,031 nodes / 2.25M edges, 29 sources [28] Powerful but static (2017) and no regulatory/dispensing info — a reference KG, not a live operational one. Ours must be live (Member/Event subgraph) + sign-off-governed.
OHDSI / OMOP Standardized Vocabularies (ATHENA) Centralized reference ontology for health-data harmonization >10M concepts, 136 vocabularies, quarterly refresh [23][24] The gold standard for "knowledge as data, versioned, released on a cadence." Adopt the model: concepts + concept_relationship as data, scheduled releases, urgent out-of-band updates.
DDInter 2.0 Curated drug-interaction DB, pharmacist-maintained ~0.24M interactions, 1,833 drugs; severity + mechanism + management + alternatives [7][8] The curated-KB row schema we adopt for interactions; proves a hospital-pharmacist curation team is the right authoring model.
DrugBank Drug knowledge base (identity, targets, interactions) Industry-standard drug reference [7] The enrichment source for drug-feature nodes (MoA, ATC, half-life) — but interaction annotations need our clinical-management layer on top.
RxNorm / RxClass / NDF-RT (NLM) Drug normalization + class federation National infrastructure [2][3][4][5] Don't build drug identity or class trees — anchor to these. RxClass federating ATC/MeSH/NDF-RT/EPC is exactly our class backbone.
AGS Beers Criteria / ACB scales Versioned geriatric medication-risk artifacts 2023 edition; ACSBC ~642 anticholinergic drugs [12][13] Risk knowledge already exists as dated, citable artifacts — model them as versioned KB rows + risk-marker nodes, not a frozen list.
Novo Nordisk StudyBuilder Production Neo4j KG over clinical standards Enterprise [16] Real-world proof a property graph runs a compliant, standards-navigating clinical knowledge system in production.

The synthesized lesson: the discovery world (PrimeKG/Hetionet) proves how to model and harmonize at scale; the infrastructure world (OHDSI/RxNorm/DDInter) proves how to govern knowledge as versioned data. Nobody has combined a curated, pharmacist-governed clinical KB + a live member/event property graph + a deterministic wellness-lane rail, served to multiple consumer engines. That combination — not any single piece — is Rx360's defensible foundation.


6 · What to build first (foundation + sequencing)

Mirrors the companion's "ground before you generate" discipline [companion §6], at the shared-layer level:

Phase 0 — Spine + schema (build first): 1. Terminology spine — RxNorm/RxClass adapters (already in the Med-Input Phase-0 plan); SNOMED/ICD for conditions. Anchor identity before anything else. 2. Curated-KB row schema + store — generalize the forgiveness table (02_…) into the §2.1 schema; versioned, effective-dated, sign-off chain. 3. Property graph + node/edge model — §1; seed with Drug/Class/Risk/Interaction from the spine; Member/Event subgraph behind the PHI boundary.

Phase 1 — Contract + rail: 4. The knowledge-layer API (§4) — one contract; provenance envelope on every response. 5. Deterministic rail in front of it — clinical-line + grounding checks (carried from companion §2.4), so engines can't emit ungrounded clinical content.

Phase 2 — Governance as data: 6. Authoring + sign-off workflow (§3.1) — author ≠ approver, knowledge-change event, gated/canary deploy as data, replay logging.

Phase 3 — Serve every engine + learn: 7. Point Scheduling, Balance Meter, Med-Input, Refill, Triage at the one layer; retire any private drug lookups. Add GraphRAG (§4.3) for interface jobs only, model-proposes-pharmacist-approves for new knowledge.

Sequencing rule of thumb: anchor before you model · curate before you serve · contract before you integrate · sign-off before you deploy · ground before you generate.


Sources

Healthcare/drug knowledge graphs at scale (precedents) 1. Building a knowledge graph to enable precision medicine — PrimeKG (Scientific Data / PMC9893183, 2023) 28. Knowledge Graphs for drug repurposing: a review of databases and methods (Briefings in Bioinformatics / PMC11426166, 2024) — Hetionet scale/static-since-2017 14. Healthcare Knowledge Graph Construction: state-of-the-art and entity resolution (arXiv 2207.03771)

Drug terminology / ontology spine 2. RxNorm overview (ScienceDirect Topics) 3. Drug Terminology and Ontology: Integration & Dissemination (NLM/LHNCBC Tech Report) 4. RxClass (NLM) 5. NLM Releases RxClass Drug Class Application (NLM Technical Bulletin, 2014) 6. Contemporary clinical decision support standards using HL7 FHIR — terminologies (ICD/SNOMED/LOINC/RxNorm) (PMC8324242)

Fall-risk-increasing drugs (FRID) + geriatric medication risk 9. Inclusion of medication-related fall risk in fall risk assessment (FRID via ATC, three groups) (PMC7648375) 10. Association of fall-risk-increasing drugs with falls — DO-HEALTH trial (BMC Geriatrics, 2024) 11. FRIDs and fall-related injuries in older adults — Ontario case-control (JAMDA, 2025) 12. 2023 American Geriatrics Society Beers Criteria (AGS) 13. Anticholinergic burden measures and older people's falls risk: systematic review (PMC8170331)

Drug-interaction knowledge bases (curated-row precedent) 7. DDInter: an online drug–drug interaction database (Nucleic Acids Research / PMC8728114, 2022) 8. DDInter 2.0: expanded coverage, new interaction types (Nucleic Acids Research, 2025)

Property graph vs RDF / graph DB at scale 15. What Is a Knowledge Graph? A Practical Guide Across RDF and Property Graphs (Taewoon Kim, 2025) 16. AWS Neptune vs Neo4j: dual model, scale, Novo Nordisk StudyBuilder (PuppyGraph, 2025) 17. RDF vs. property graphs: choosing the right approach for a knowledge graph (Neo4j) 18. Achieve Unrivaled Speed and Scalability With Neo4j — billions of nodes (Neo4j) 19. Architectural differences between Neptune and Neo4j — replicas, storage (AWS docs)

Knowledge-as-data: FHIR clinical reasoning, terminology service, OHDSI 20. Clinical reasoning — knowledge artifact representation: PlanDefinition/Library (FHIR R6) 21. FHIR Terminology Service — CodeSystem/ValueSet/ConceptMap (FHIR R6) 22. Canonical Resource Management Infrastructure IG — content lifecycle for knowledge artifacts (HL7 CRMI) 23. OHDSI Standardized Vocabularies — centralized reference ontology, >10M concepts (JAMIA / PMC10873827, 2024) 24. Standardized Vocabularies & ATHENA — refresh cadence (The Book of OHDSI, ch.5)

GraphRAG / serving the knowledge layer 25. Retrieval-Augmented Generation with Graphs (GraphRAG) (arXiv 2501.00309) 26. What is GraphRAG? (IBM) 27. Graph RAG Guide 2025: architecture, accuracy on schema-bound queries (Salfati Group)