Skip to content

The Curated Drug KB — sharing it + the tagging schema for the model

Date: 2026-06-04 · From: Gene (Pharmacy Ops) · For: Faraz + Emil (+ Dr. B for the clinical content) Answers two questions: should we share the Smart-Scheduling curated KB? (yes — it's the clinical data the engine runs on) and how should it be tagged so the model uses it safely? (the schema below).

⚠ The clinical content is PRELIMINARY — illustrative reference, not production until a pharmacist (Dr. B) signs off. Share it with Faraz for shape and structure; gate it behind the sign-off before it drives any member-facing behavior.


1 · Yes — share it. Here's what it is and where it plugs in.

The Smart-Scheduling KB we curated (Smart_Scheduling/KB/02_Drug_Forgiveness_Tolerance_Data.md, 27 drug classes) is the curated clinical reference the engine runs on: per drug class — cadence, half-life, forgiveness/tolerance window, missed-dose handling, food/timing rules, and the high-stakes/NTI flags. It's the data behind: - the tolerance() MCP tool (Sprint-A/B) — tolerance(rxcui|class) → {cadence, tolerance_window, food_rules, high_stakes}, - the Scheduling engine (cadence/tolerance) + the Balance Meter (FRID/high-risk), - and the demo's data/knowledge.json — which is a tiny version of this same table.

In production it lives as versioned rows in the lakehouse / curated KB (knowledge-as-data), served through the MCP server with a provenance envelope — not hardcoded. Copied into the Faraz folder so he has the content + the shape.

2 · The tagging schema (the "tags the model needs")

Every curated-KB entry carries this metadata. The point: the tags are what let the model use the data safely and traceably — they're the machine-readable version of "this is clinical reference for timing, not dosing advice."

Tag Values What the model / system does with it
kb_entry_id e.g. kb:warfarin:tolerance:v3 the grounding handle — every fact the model uses must cite this; the deterministic rail blocks any clinical content without one
version · effective_date semver · date replay/audit which version drove a decision
status preliminary | validated a preliminary entry may NOT drive production member output until sign-off
source Assawasuwannakit2015 / AARDEX / DailyMed / curated provenance
author · approver name author ≠ approver (governance; no self-approval)
clinical_line true | false true → the model may never surface it member-facing without the rail / a pharmacist. It's reference for timing, never advice
use timing-only | context | internal-scoring constrains how the model may use the entry (e.g., tolerance = timing a reminder, not "take it late")
member_facing never | wellness-safe what may surface to the member at all
high_risk bool model routes to explicit-confirm / pharmacist, never auto
nti bool narrow therapeutic index → extra caution + escalation
frid bool fall-risk-increasing → feeds Balance Meter + the cross-engine med-change event
prn bool no scheduled reminder (track usage instead)
drug_class RxClass code(s) the graph uses it for duplicate-therapy / interaction / FRID linking
lookup structured | semantic the structured-first retriever serves this from the table, not the vector store
evidence_strength high | moderate | low confidence weighting for the entry

A sample tagged entry (the production shape)

{
  "kb_entry_id": "kb:warfarin:tolerance:v3",
  "rxcui": "855332", "ingredient": "warfarin", "drug_class": ["anticoagulants"],
  "cadence": "daily", "tolerance_window": "narrow", "food_rules": "consistent vitamin-K intake",
  "tags": { "clinical_line": true, "use": "timing-only", "member_facing": "wellness-safe",
            "high_risk": true, "nti": true, "frid": true, "prn": false,
            "lookup": "structured", "evidence_strength": "high" },
  "provenance": { "source": "curated", "author": "Dr. B", "approver": null,
                  "status": "preliminary", "version": "0.1", "effective_date": "2026-06-04" }
}
Every MCP response wraps the answer in {value, source, kb_entry_id, version, clinical_line_flag} — so the tags travel with the data to every engine, and the rail can enforce them.

3 · Why this matters for the model (the safety logic)

  • The model never invents clinical facts — it retrieves tagged entries via the MCP server and cites the kb_entry_id. No citation → the rail blocks it.
  • clinical_line: true + use: timing-only together tell the system: this can shape a reminder's timing, but it can never become member-facing dosing advice. That's the wellness/SaMD line, encoded per entry.
  • status: preliminary is the sign-off gate in data form: the pipeline refuses to let a preliminary entry drive production member output. When Dr. B signs off, status → validated, approver is set — no code change.

4 · How Faraz uses it

  1. Ingest 02_Drug_Forgiveness_Tolerance_Data as the curated-KB seed (rows, not prose) — keep the preliminary banner.
  2. Apply the tagging schema (§2) to every row.
  3. Serve it through the tolerance() MCP tool with the provenance envelope.
  4. The rail enforces the clinical_line / kb_entry_id tags on output.
  5. Gate preliminaryvalidated behind Dr. B's sign-off before production.

Companions: Smart_Scheduling/KB/02_Drug_Forgiveness_Tolerance_Data (the clinical content) · AI_Foundation_Sprint_A-B_Specs (the MCP tools + the provenance envelope) · AI_Foundation/KB/01_Knowledge_Layer_KB_KG (knowledge-as-data + the curated-KB row schema).