Skip to content

Regulatory basis

Scope of this document

This page explains the regulatory reasoning behind the system's design. It is not legal or regulatory advice, and this system is not a medical device, not a clinical decision support product, and not in clinical use.

The design constraint that shaped the architecture

The 21st Century Cures Act §3060 excludes certain clinical decision support (CDS) software from the medical device definition, and the FDA's Clinical Decision Support Software guidance (September 2022) interprets it. Non-device CDS must, among other criteria, enable the user to independently review the basis for its output rather than relying primarily on it, and must not acquire, process or analyze a medical image or signal.

That criterion is why:

  • every clinical claim carries a citation, and coverage is measured and enforced in guardrails/citation_check.py rather than requested in a prompt (docs/architecture/decisions/D-A3-1-the-sandwich-has-two-independent-halves.md);
  • citations point at real public-domain pages a patient can actually open (docs/architecture/decisions/D-A3-4-citations-are-real-and-that-is-free.md) — a citation that cannot be independently reviewed satisfies nothing;
  • reference ranges are quoted rather than interpreted (store/models.py::ReferenceRange);
  • the answer shows which record rows it read (schemas/answer.py::Claim.evidence_refs);
  • the system directs to care rather than characterising urgency (guardrails/templates.py) — it never says "you are having a heart attack", it says "seek emergency care now".

Citation coverage is therefore not a quality metric here. It is a design constraint traceable to a named criterion, and being able to point at the code that enforces it is a stronger position than any amount of domain vocabulary.

HIPAA minimum necessary — 45 CFR 164.502(b)

The minimum-necessary standard requires limiting use, disclosure and request of protected health information to what is reasonably necessary for the purpose. Two controls implement this directly, not as a prompt instruction:

  • Refusals short-circuit before retrieval. Any non-allow pre-flight decision binds registry.education_only_scope(), from which every patient-scoped tool is absent (tools/registry.py, docs/architecture/decisions/D-A3-6-publication-is-deterministic-and-refusals-short-circuit.md). A refused or escalated question never reaches a patient record.
  • Row caps. ScopedToolExecutor clamps every limit argument to the scope's row_cap regardless of what the model requests (tools/scoping.py), so a run cannot pull more of the record than the scope allows.

HIPAA Safe Harbor de-identification — 45 CFR 164.514(b)

Safe Harbor lists 18 identifier categories that must be removed for data to be considered de-identified. This system never reaches that question in the first place: every patient record is generated by Synthea (Apache-2.0), a synthetic-patient-population simulator. There is no real or re-identifiable individual behind any record this system reads, and there is no configuration path to point it at real data.

ONC information blocking / 21st Century Cures Act Final Rule

The Cures Act Final Rule (45 CFR Part 171) establishes that patients are entitled to their own electronic health information without unreasonable delay or interference. This is the regulatory reason a patient-facing record-access assistant exists as a category at all — the system's base tier (record lookup, lab and medication education) is squarely inside what the rule intends patients to be able to get.

Section 1557 language access — 42 U.S.C. §18116 / 45 CFR Part 92

The ACA §1557 language-access requirements require meaningful access for people with limited English proficiency. This is why a non-English question is not silently answered badly: canonical case 16 detects the question's language (guardrails/language.py) and responds with a stated limitation in English plus a route to the care team (guardrails/templates.py::language_limitation_template), rather than either guessing at a translation or refusing outright. base does not yet answer in Spanish; that is an honest, disclosed limitation, not a silent failure, and full language support is deferred to Stage 2 (docs/PLAN.md §7 Stretch).

The crisis path — 988 Suicide & Crisis Lifeline

A self-harm red flag routes to a dedicated crisis path (guardrails/templates.py::crisis_template), distinct from the medical emergency path in both resource and wording (docs/PLAN.md §4.4): the 988 Suicide & Crisis Lifeline is available 24/7 by call or text, and is named explicitly rather than folded into a generic "seek care" message.

Red-flag rules, cited rule by rule

Every escalation rule cites a real, public-domain patient-facing source, and the build fails if an escalation rule is added without one (data/generate_policy_rules.py::validate):

Category Rules Source
Cardiac rf-cardiac-chest-pain, rf-cardiac-radiating, rf-cardiac-associated MedlinePlus — Heart Attack
Stroke rf-stroke-face-arm-speech, rf-stroke-sudden-neuro MedlinePlus — Stroke
Anaphylaxis rf-anaphylaxis MedlinePlus — Anaphylaxis
Self-harm rf-self-harm MedlinePlus — Suicide and Suicidal Thoughts, 988

The scope rules (dosing, medication change, diagnosis requests, out-of-domain questions, interaction and symptom-management questions) carry no citation, and deliberately so: they are boundaries this project set, not clinical findings, and that distinction is worth keeping visible in the table rather than dressing a design choice up as evidence.

Education-source terms, verified before the pipeline was written

The plan required these to be checked against the primary sources rather than assumed, because the whole citation argument above rests on them.

Service Terms Rate limit
MedlinePlus Connect Free; no API key, no registration. Linking to and displaying returned data is permitted; copying MedlinePlus pages is not. NLM recommends caching for 12–24 hours 100 requests/minute per IP
MedlinePlus Web service Free of charge; no registration or licensing 85 requests/minute per IP
RxNav / RxNorm Free; no licence needed. RxClass/SNOMED CT is not used, so its Affiliate licence does not apply 20 requests/second per IP

So the education cache is a build artifact, not a corpus: it holds only the fields the service returns — title, URL, summary, attribution — with a retrieval timestamp and a TTL inside NLM's recommended window. It is never committed and the application never mirrors a MedlinePlus page. Attribution appears in NOTICE.md, including RxNav's required verbatim statement.

The LOINC terminology table is deliberately not a dependency, so its licence agreement never applies. Synthea's observations already carry LOINC codes and MedlinePlus Connect accepts a code directly; codes pass through, the table is never downloaded or redistributed.

Two disclosures made deliberately

No clinician has reviewed the safety rules. Every emergency red-flag rule is derived from a published patient-facing source and cites it by URL, so no rule rests on the author's own clinical judgement. But no clinician reviewed the resulting table. Stating that plainly is the honest position; an uncited table reviewed informally would be worse than a cited one reviewed by nobody.

The reference ranges are illustrative. data/lab_reference_ranges.csv is adult-general and cited to published sources. It is not any laboratory's own reference intervals, and real ranges vary by assay, method, age and sex.