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" }
}
{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-onlytogether 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: preliminaryis 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,approveris set — no code change.
4 · How Faraz uses it¶
- Ingest
02_Drug_Forgiveness_Tolerance_Dataas the curated-KB seed (rows, not prose) — keep the preliminary banner. - Apply the tagging schema (§2) to every row.
- Serve it through the
tolerance()MCP tool with the provenance envelope. - The rail enforces the
clinical_line/kb_entry_idtags on output. - Gate
preliminary→validatedbehind 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).