
Structured Clinical Document Reasoning Platform
Full-Stack
A hierarchy-aware, provenance-tracked reasoning graph for healthcare data, designed to answer clinical, billing, and quality-reporting questions from one shared ontology.
The platform combines structured clinical knowledge, document-level evidence, temporal relationships, ontology mappings, and semantic similarity in a single reasoning layer. Deterministic graph queries and RAG-assisted natural-language querying sit on top of the same underlying data rather than operating as separate systems.

Role
Independent solo project: architecture, ontology design, and system build
What makes this architecture different
This project is less about extracting medical concepts from text and more about preserving the relationships between them so those concepts can still be reasoned over later.
The architecture treats a clinical record as a connected system rather than a collection of isolated text snippets. Concepts retain their original identity when they participate in larger concepts. Findings remain connected to the evidence that produced them. Dates retain their different meanings. Crosswalks between terminology systems become queryable relationships instead of dead-end mappings. And uncertain resolutions retain the scope at which they were actually established.
The result is a reasoning layer designed around several dimensions of clinical information at once:
- HIERARCHY: concepts retain their position within clinical ontologies.
- COMPOSITION: individual concepts can combine into a higher-level concept without erasing the original atoms.
- ATTACHMENT: findings can be resolved to the body part or clinical context they actually describe rather than simply the nearest mention.
- TIME: clinical effective dates and system-recorded dates remain distinct.
- PROVENANCE: every resolved fact can be traced back to its source document and text span.
- GRANULARITY: the system records whether a relationship was established at phrase, sentence, paragraph, or document scope.
- CROSS-ONTOLOGY RELATIONSHIPS: clinical concepts can be reconciled across SNOMED, ICD-O, and ICD-10-CM rather than relying exclusively on direct mappings.
- UNCERTAINTY: low-confidence relationships can remain explicitly uncertain and be routed for review instead of being silently promoted to facts.
Each is unpacked below.
Why clinical AI reasoning is still fragile
Clinical AI reasoning breaks down in places that are easy to miss because the individual pieces can all look correct.
A RAG system can retrieve text that is semantically relevant, but it can't verify a numeric threshold or a temporal rule the way eligibility logic requires. Official terminology crosswalks can tell you that two codes are related, but they are usually lookup tables rather than queryable structure, so they don't expose the hierarchy or composition that produced a clinical concept. And even accurate extracted data can fail to answer the actual question if the system returns raw evidence instead of a clear, defensible conclusion.
The harder problem is that these aren't independent gaps.
A clinical answer may depend on what the concept is, where it belongs, what it is composed of, when it became true, when it was recorded, which document established it, and how confidently the system resolved the relationship. Flatten those dimensions into text chunks, terminal codes, or a single confidence score, and the information needed for reasoning is already gone before the model ever sees the question.
That is why RAG alone is not enough. Retrieval answers “what looks relevant?” It does not, by itself, answer “what relationship is actually true here?” or “does this patient satisfy this rule?”
And the stakes are not theoretical. In a 2023 JAMA Oncology evaluation of ChatGPT treatment recommendations across breast, prostate, and lung cancer, 35 of 102 outputs that provided a treatment recommendation (34.3%) also recommended one or more treatments that were not concordant with NCCN guidelines, while 13 of 104 outputs (12.5%) contained at least one hallucinated treatment.
The architecture is designed around that gap: preserve the clinical structure first, use semantic similarity where relationships are genuinely ambiguous, and then reason over those resolved relationships with explicit structure, provenance, and deterministic rules.
Compositional concept model

Body part and morphology compose into a diagnosis without erasing either underlying concept.
A common extraction pattern turns a phrase such as “breast cancer” into a single terminal concept. That is convenient for retrieval, but it can discard useful structure: “breast” may also appear independently in imaging, anatomy, family history, or other clinical contexts.
This model treats the concepts as composable rather than replaceable.
A pathology note such as:
“carcinoma identified in the left breast, moderately differentiated”
can produce independent concepts for left breast and carcinoma, while also creating a composite diagnosis representing their clinical relationship.
Nothing is erased. The composite concept is added on top of the underlying atoms.
That distinction matters when the same patient record later needs to answer questions at different levels of abstraction: the system can reason about the diagnosis as a whole while still being able to query the anatomical and morphological concepts that formed it.
ICD-O as a reconciliation bridge

Most systems treat ICD-O as a dead-end crosswalk hanging off a SNOMED concept. This structure treats it as the actual reconciliation point it is: ICD-O-3 topography is derived from ICD-10 Chapter II, and SEER maintains official ICD-O to ICD-10-CM conversion tables. Modeling that relationship explicitly means a SNOMED clinical concept and its ICD-10-CM billing code can be reconciled through ICD-O even when a direct mapping is ambiguous or one-to-many, a common occurrence in oncology coding.
Concrete example: a clinical note documents “invasive ductal carcinoma, left breast.” The SNOMED finding maps to ICD-O topography C50.9 and morphology 8500/3, which resolves via the bridge to ICD-10-CM C50.912, the specific laterality-coded billing diagnosis, without a human having to manually reconcile the clinical description against the billing code.
The important part is not just that the final code is correct. The path remains visible: clinical finding → SNOMED → ICD-O topography/morphology → ICD-10-CM. That makes the reconciliation itself a queryable relationship rather than a hidden lookup step.
One patient, every source, two clocks

Clinical documents and billing claims can describe the same patient while recording time in fundamentally different ways.
A diagnosis can be entered into the system today but describe a condition that became clinically relevant years earlier. A claim can have a service date that precedes its adjudication or logging date.
The graph therefore keeps both:
- Effective date: when the clinical event or condition actually applies.
- Logged date: when the system recorded the information.
Every mention and claim remains connected to the same patient-level graph.
That makes it possible to reason across documents, encounters, and claims without forcing everything onto a single timeline.
Two dates, one query in practice

The distinction becomes useful when the question itself depends on the difference between the two clocks.
For example:
“Flag any diagnosis logged more than 30 days after its effective date.”
That is not a semantic retrieval problem. It is a deterministic temporal relationship.
The graph can compare the two dates directly and surface documentation-lag patterns that a single-date representation would hide.
The same data can answer a different question:
“Which labs occurred within 90 days of surgery?”
That query uses effective dates rather than the logging delay.
One graph therefore supports different interpretations of time without changing the underlying data model.
Multidimensional clinical reasoning
The architecture is built around a simple premise:
A clinical fact is rarely just a concept.
Its meaning can depend on what it is, where it belongs, what it is composed of, when it became true, when it was recorded, what source established it, how precisely it was resolved, and how it relates to other concepts.
Those dimensions are modeled independently but connected through the graph.
Consider a single pathology finding. The system may need to know:
- what the morphology is,
- which anatomical site it belongs to,
- whether that site was explicitly stated or inferred,
- what other concepts compose the diagnosis,
- when the finding became clinically effective,
- which document established it,
- where in that document the evidence appears,
- how confidently the relationship was resolved,
- and how the resulting clinical concept maps into downstream coding systems.
No single retrieval operation answers all of those questions.
The graph provides the structure between them.
Vector similarity can then be used selectively where the problem is genuinely fuzzy, for example determining which anatomical context a morphology mention belongs to when the document structure is ambiguous.
This makes semantic retrieval a component of the reasoning system rather than a substitute for one.
Two ways to ask the same question

The graph is the source of truth in both modes.
RAG-assisted mode provides a natural-language interface. An LLM can interpret an open-ended question, retrieve the relevant graph-backed evidence, and synthesize an answer. This is useful for exploration and conversational access, but the reasoning path is less deterministic.
Deterministic graph mode answers the same class of question through explicit graph queries and rules, without an LLM participating in the reasoning loop. The result can be traced through the graph and back to its source evidence.
The important architectural decision is that these are not two separate knowledge bases.
They are two interfaces to the same underlying representation.
That means a customer can choose the reasoning mode appropriate to the task rather than forcing every workflow into either “AI chat” or “traditional rules.”
Resolving attachment, not just meaning

One of the harder problems in clinical NLP is not determining what a phrase means. It is determining what that phrase belongs to.
Clinical documentation frequently separates an anatomical site from the finding associated with it.
A pathology report might describe a left breast biopsy in one section and a right axillary FNA in another, then later state:
“carcinoma identified, moderately differentiated”
without repeating the specimen or anatomical site.
A proximity-based system might attach the morphology to whichever body-part mention happens to be closest to the text.
That is not reliable enough.
Here, vector similarity is used for attachment resolution rather than simply document retrieval. The surrounding context of the morphology mention is compared with the contexts of candidate anatomical sites, producing a scored relationship between the finding and the site it most likely describes.
The winning relationship is written into the graph.
Low-confidence relationships remain explicitly uncertain and can be routed for human review instead of being silently accepted.
This is deliberately different from claiming that embeddings “understand” the clinical relationship. The embedding supplies evidence for a fuzzy association; the graph records the resulting relationship, its score, and its provenance.
True pronominal coreference remains a separate problem. A sentence such as “it was treated with lumpectomy” may refer to a diagnosis mentioned earlier without containing enough concept-specific text for attachment scoring alone to resolve it.
That limitation is handled as uncertainty rather than hidden behind a confident-looking answer.
One more signal: context, not just co-occurrence
The same weighted-evidence mechanism extends naturally to a narrower, older problem: deciding whether two concepts in a document should be related at all.
The system I worked on handled this with hard-coded span logic: to link concept A and concept B, scan the text between them for specific blocking terms, e.g., a procedure or a negation, and manually program that check for every relationship type worth extracting. It worked, but it didn't scale. Every new relationship needed a new rule, and the rule count grew with how much we wanted the system to notice, not with anything about the underlying language.
Soft, learned relevance between two entities, rather than a hard include/exclude gate, isn't a new idea in NLP generally; it's been the mainstream approach in relation extraction for a long time. But the system I worked on stuck with hard rules for a real reason, not an oversight: they're auditable in a way statistical relation extraction usually isn't. You can point to exactly which trigger term blocked exactly which relationship.
The move here keeps both: intervening concepts become one more scored signal inside the same graph structure already used for attachment resolution and event linking, instead of a hard-coded rule. The score is still traceable, still an inspectable edge property, not a buried weight, so the auditability that justified hard rules in the original system doesn't have to be sacrificed to get the scaling benefit.
Corroborating evidence: linking mentions to the same clinical event

Attachment resolution answers “which body part does this finding belong to.” A related but separate question is whether multiple, independently resolved mentions, possibly from different documents, different modalities, different points in a workup, actually describe the same underlying clinical event.
No single mention typically states this outright. A mammogram report says “3 o'clock mass, left breast.” A procedure note says “upper outer quadrant,” with the laterality only established earlier in the same document. A pathology report says “invasive ductal carcinoma, moderately differentiated,” with no laterality stated anywhere in it at all. Each resolves cleanly on its own. Nothing forces the system to recognize that all three are talking about the same lesion.
The fix borrows a well-established idea from a different corner of health data, probabilistic record linkage, and applies it one level down from where it's normally used.
Record linkage (Fellegi-Sunter, 1969, still the backbone of most patient-matching systems today) works by combining several individually weak signals, a matching birthdate, a similar name, a shared address, into a single confidence score for whether two records describe the same person. No one field is proof by itself; several weak signals agreeing is strong evidence.
This applies the same evidence-combination logic to findings instead of patients:
- Body-part relation strength, via the ICD-O hierarchy: how anatomically close are the sites each mention describes?
- Temporal proximity: how close together in time did these mentions occur?
- Procedure-type match: does the sequence of imaging, biopsy, and pathology follow a coherent diagnostic workup?
- Shared or related document metadata: do the documents reference the same diagnosis code, encounter, or ordering provider?
Each signal alone is circumstantial. A shared body part could be coincidence. Two events two weeks apart could be unrelated. But when several independent signals agree, the combined confidence that these mentions describe the same clinical event is far stronger than any single signal could support: the same “several weak signals, one strong conclusion” logic behind record linkage, just re-targeted at findings instead of people.
Graph-wise, this means resolved mentions don't just stand alone once attached to a body part or concept. They can also link into a shared clinical-event node, with each contributing edge carrying its own signal type and score, and the event node carrying the combined confidence. That combined score is fully inspectable: not a black-box result, but a visible sum of exactly which evidence contributed and how much.
Record linkage at the patient level is mature and widely deployed. Applying that same evidence-combination logic at the finding level, tying together a diagnostic workup's separate mentions into one coherent, confidence-scored event, doesn't seem to be common practice in clinical NLP as far as I've seen, though I haven't done an exhaustive survey of the field. It's a promising direction rather than a proven one at this stage: the weighting scheme, the right signal set, and how well it holds up on real clinical text are all open questions this architecture hasn't answered yet. But it's the kind of idea worth testing, because it moves individually-resolved facts a step closer to something a person could actually cross-examine.
One document, many spans

Every phrase, sentence, and larger context window is represented as a range of character offsets into one stored copy of the original document.
A phrase such as “left breast” can therefore retain its exact location while also being associated with the surrounding sentence, paragraph, or section without duplicating the text itself.
This approach provides two useful properties.
First, storage remains efficient. Context is represented by offsets rather than repeated copies of the same clinical text.
Second, provenance remains precise.
A downstream consumer can distinguish between a relationship established directly from a phrase and one established only from a larger surrounding context.
That becomes the basis for the platform's resolution-scope precision gauge.
A phrase-level match can represent a highly specific relationship. A sentence-level or paragraph-level match represents a broader inference. The system preserves that distinction rather than treating every resolved relationship as equally precise.
This also creates a useful path for human review: uncertainty is not simply a confidence score attached to a black-box result. The system can show how much text was required to establish the relationship in the first place.
Adding new terminology without reprocessing everything

Clinical terminology changes.
A new synonym or concept should not require the entire corpus to be processed again if the expensive linguistic work has already been completed.
The architecture therefore retains an indexed copy of the underlying document text separately from the terminology currently known to the extraction system.
When a new synonym is added, the system can search the existing corpus for that exact term, recover its character offsets, and create the corresponding mentions and relationships.
Sentence detection, tokenization, and other expensive stages do not need to run again because the stored document representation already contains the information those stages produced.
The approach also deliberately separates exact matching from semantic matching.
Exact indexed lookup handles the common case cheaply and precisely. Embedding-based matching remains available when the language is paraphrased rather than literally expressed.
The result is incremental terminology expansion instead of repeated full-corpus processing.
One graph, several initiatives
The same reasoning core can support different healthcare workflows without creating a separate data model for each one.
Clinical care
Trial eligibility matching can combine structured patient history with ClinicalTrials.gov criteria.
Chronic disease monitoring can reason over measurements such as A1c across time rather than treating each result as an isolated document mention.
Patient history can be traversed across clinical documents, encounters, and other sources from a common patient node.
Billing and revenue integrity
The same provenance and ontology layers can support documentation-to-code auditing, claims anomaly detection, and under- or overbilling review.
The SNOMED, ICD-O, and ICD-10-CM relationships provide structure for reconciling clinical documentation with downstream coding.
Quality and safety
The graph can support registry and quality-measure reporting, including source-traceable population fields, as well as longitudinal tracking for quality and patient-safety indicators.
The important point is not that one system performs three unrelated jobs.
It is that the same reasoning infrastructure can be reused while the rules and outputs change by initiative.
One graph. One ontology layer. One provenance model. Different reasoning rules.
Where this holds up, and where it doesn't yet
Strengths
- Grounds reasoning in real domain structure, not just semantic similarity
- Full provenance to source document and span, on every answer, down to the exact resolution scope it was matched at
- Combines independently weak signals, like body-part relation, temporal proximity, and shared metadata, into a single inspectable confidence score linking mentions across documents to the same clinical event
- Generalizes across code systems, proven with a SNOMED/ICD-O/RxNorm ontology applied to two unrelated clinical domains
- Same graph and provenance layer extends to billing/claims and quality-reporting use cases, not just clinical narrative
- Deterministic mode gives an auditable option most RAG-only systems don't offer
- Concept and synonym updates are indexed lookups, not full-corpus reprocessing
Open limitations
- Ontology and crosswalk coverage is currently narrow: hand-built, not exhaustive
- True pronominal coreference resolution isn't resolved automatically by attachment scoring, though the same precision-gauge flagging that handles any other low-confidence match catches it and routes it to human review rather than leaving it unaddressed
- Corroborating-evidence linking is a promising direction, not a validated one; the right signal set and weighting scheme are still open questions
- Not yet validated against real clinical data: MIMIC access is pending
- Output usability is still unproven with an actual end user
- Single-developer build, not yet production-hardened or scale-tested
Current status
MVP scoped to two tracks (breast cancer, for oncology/registry, and A1c monitoring, for chronic disease), both matched against ClinicalTrials.gov.
- Architecture locked (done): graph schema, compositional model, ICD-O bridge, bitemporal design, resolution-scope gauge, corroborating-evidence linking, and incremental-update strategy finalized.
- Ontology & data ingestion (planned): SNOMED/ICD-O/NAACCR seed data and synthetic clinical notes for both tracks.
- Reasoning rules & trial matching (planned): 3 to 5 rules live; ClinicalTrials.gov ingestion and matching, both tracks.
- Dual-mode demo (planned): RAG and deterministic modes, toggleable, with full provenance on output.
The larger idea
Most clinical AI systems ask:
“What text is relevant to this question?”
This architecture asks a harder question:
“What relationships have to remain true for this information to be reasoned over correctly?”
and
“How can we preserve aggregate context for questions we can't predict?”
Those questions lead to a different kind of architecture: one designed not only to retrieve the right evidence, but to preserve the relationships and context that make that evidence meaningful.. even for questions we haven't thought to ask yet.
The text is still there. The codes are still there. Embeddings are still useful. LLMs are still useful.
But none of them has to carry the entire burden of reasoning.
The graph preserves the structure and aggregate context that allow the evidence to remain meaningful as new questions emerge.
