Skip to content

Attributed Fact Extension

Canonical../StructureDefinition/nexus-attributed-fact
Statusdraft (experimental) · 1.26.0
BaseExtension (constraint)
ContextProvenance (element)
SourceFSH · JSON

One factual statement in a piece of AI-generated text, together with the citation(s) that back it: verbatim quotes from the source material the statement was derived from.

FSH

The authored source of truth: extensions/AttributedFactExtension.fsh (edit on GitHub). One FSH file may define several related artifacts.

// AttributedFactExtension.fsh
// Per-fact citation trail for AI-generated text, carried on Provenance.
//
// WHY. An AI-generated summary is a set of factual statements, and the AI Harness's
// generation contract requires every statement to be backed by at least one verbatim
// quote from the source material it was derived from -- a fact with no citation is
// rejected at generation time, never surfaced. When such a summary (or its provenance)
// is persisted, that per-fact trail must survive with full fidelity: Provenance.entity
// says which resources the activity read, but not which fact came from which passage.
// This extension is the FHIR home for that finer grain.
//
// THE WIRE SCHEMA THIS MIRRORS. The harness emits facts as
//   { statement: string, citations: [ { chunk: string, quote: string }, ... ] }
// with citations required non-empty. The mapping is 1:1 and lossless:
//   statement          -> extension[statement].valueString
//   citations[i].chunk -> extension[citation][i].extension[chunk].valueString
//   citations[i].quote -> extension[citation][i].extension[quote].valueString
// `citation 1..*` carries the non-empty requirement. The optional `source` sub-extension
// is additive (no wire counterpart yet): a FHIR-native pointer from a citation to the
// Provenance.entity resource the chunk was drawn from.

Alias: $NexusAttributedFact = ../StructureDefinition/nexus-attributed-fact

// The rules cardinality cannot state. `statement 1..1` and `quote 1..1` require the elements to be
// PRESENT; neither stops them being the empty string, and an empty one is worse than a missing one:
// it satisfies every structural check while asserting nothing. An empty quote is a citation that
// cites no text, which makes the fact unauditable -- exactly the property this extension exists to
// provide -- and it would pass silently into the record as a green, fully-conformant citation.
//
// Error severity, not warning: a producer emitting these is not partially right. The generating
// contract refuses to emit a fact it cannot cite, so an empty quote means the trail was lost
// somewhere between generation and persistence, and that is worth failing on rather than storing.
Invariant:   attributed-fact-citations-are-substantive
Description: "Every citation must carry a non-empty verbatim quote, and the statement itself must be non-empty -- an empty string satisfies the cardinality while citing nothing, leaving a fact that cannot be audited against its source"
Severity:    #error
// `value.ofType(string)`, NOT `valueString`. Extension.value[x] is a CHOICE, so the publisher
// rejects the shorthand -- "The name 'valueString' is not valid for any of the possible types:
// [Extension]" -- and an invariant whose expression fails to EVALUATE is not enforced at all. This
// one is Severity #error and had been checking nothing since it was written.
Expression:  "extension('statement').value.ofType(string) != '' and extension('citation').all(extension('quote').value.ofType(string) != '')"

Extension: NexusAttributedFact
Id: nexus-attributed-fact
Title: "Attributed Fact"
Description: """
One factual statement in a piece of AI-generated text, together with the citation(s)
that back it: verbatim quotes from the source material the statement was derived from.

Repeats, in order, to carry the full fact list of a generated summary -- order is
significant and MUST be preserved, because the facts compose the summary text. Each
fact carries at least one citation by construction: the generating pipeline refuses to
emit a citation-free fact, and this extension makes that guarantee structural
(`citation` is `1..*`).

The citation's `chunk` is the generating run's own label for the passage of source
material the quote was copied from (for example `c3`). Chunk labels are opaque and are
only meaningful relative to the run that produced this Provenance -- they are stable
within one Provenance instance, not across instances. The `quote` is the verbatim,
character-for-character text of the cited passage; it is the auditable part, and it
remains checkable against the source document even after the run's chunking is gone.
The optional `source` reference ties a citation to the specific `Provenance.entity`
resource the chunk was drawn from, when the producer can resolve it.

This grain is deliberately finer than `Provenance.entity`: entity records which
resources the activity read; this extension records which statement rests on which
passage. A consumer that only needs "what were the inputs" should read `entity` and
ignore this extension.
"""
* ^url = $NexusAttributedFact
* ^context[0].type = #element
* ^context[0].expression = "Provenance"
* ^status = #draft
* ^experimental = true
* obeys attributed-fact-citations-are-substantive
* . ^short = "One AI-generated factual statement and the verbatim quote(s) backing it"

* extension contains
    statement 1..1 MS and
    citation 1..* MS

* extension[statement].value[x] only string
* extension[statement] ^short = "The factual statement, as it appears in the generated text"

* extension[citation] ^short = "A passage of source material backing the statement (at least one required)"
* extension[citation] ^comment = "Required non-empty: a fact that cannot cite its source does not belong in the record. Multiple citations mean the statement synthesizes more than one passage."
* extension[citation].extension contains
    chunk 1..1 MS and
    quote 1..1 MS and
    source 0..1

* extension[citation].extension[chunk].value[x] only string
* extension[citation].extension[chunk] ^short = "Producer's label for the cited passage (e.g. c3); opaque, run-relative"
* extension[citation].extension[quote].value[x] only string
* extension[citation].extension[quote] ^short = "Verbatim quote, character-for-character from the cited passage"
* extension[citation].extension[source].value[x] only Reference
* extension[citation].extension[source] ^short = "The Provenance.entity resource the passage was drawn from, when resolvable"
* extension[citation].extension[source] ^comment = "SHOULD match the `what` of one of this Provenance's `entity` repeats. May be identifier-only per the logical-reference model."