Skip to content

feat(citation): measure citation coverage and mark unsupported statements - #164

Merged
mrsibe merged 1 commit into
mainfrom
fix/156-onto-main
Sep 28, 2026
Merged

mrsibe merged 1 commit into
mainfrom
fix/156-onto-main

Conversation

@mrsibe

@mrsibe mrsibe commented Sep 28, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Re-delivers #156 (citation coverage) onto main.

Why?

#163 was merged into feat/155-exact-passage-citation rather than main, because its base was the #155 branch. origin/main contains #161 and #162 but not #156's changes. The #155 commit on that branch is also the pre-squash SHA, so a normal PR from it would re-show #155.

This branch is origin/main + a cherry-pick of the #156 commit, so the diff is exactly #156 and nothing else.

Related issue

Fixes #156
Related to #154, #163

What changed

Same content as #163:

  • classifyClaimSupport() (shared, pure): cited / uncited / invalid-citation / inference per sentence, plus coverage, unsupportedRate, invalidRate. Marker-only fragments attach to the preceding sentence.
  • Sentence segmentation moves to shared/utils/sentenceSegmentation so candidates ([Feat] Exact-passage citation: the model cites source spans, not chunks #155) and coverage agree.
  • Prompt asks for a citation per factual sentence and [inference] for the model's own claims; the remark plugin keeps [inference] out of the rendered body.
  • AnswerCoverage shows a notice only when something is unsupported.

How was this tested?

Checklist

  • I have reviewed my own changes.
  • npm run typecheck passes.
  • npm run build passes.
  • I have tested the affected user workflow.
  • I have not included unrelated changes.
  • I have updated documentation when necessary.

Desktop / build changes

  • Not applicable

…ents

Report the one deterministic grounding property: does a sentence carry a citation
that resolves to a real span. Deliberately not whether the citation proves the
sentence — that is semantic entailment, and a rule that pretended to answer it
would produce a wrong "grounded" verdict, which is worse than none.

- classifyClaimSupport() (shared, pure) splits the answer and returns
  cited / uncited / invalid-citation / inference per sentence, plus coverage,
  unsupportedRate and invalidRate. Marker-only fragments such as "A is true. [1]"
  attach to the preceding sentence, because models write the marker after the
  period.
- Sentence segmentation moves to shared/utils/sentenceSegmentation so candidates
  (#155) and coverage agree on what a sentence is.
- The prompt asks for a citation on every factual sentence and [inference] for a
  claim the model adds itself; the remark plugin keeps [inference] out of the
  rendered body.
- AnswerCoverage shows a notice only when something is unsupported; a fully cited
  answer gets no line.

Verified: npm run typecheck; npm test (363 pass); npm run check:design;
npm run build; RAG eval output byte-identical to docs/eval/baseline-v1.4.json.

Scoped out: inline per-sentence marking (the notice is aggregate), and live-model
behaviour. The #75 harness runs no model, so coverage is not measured there — a
model-driven answer eval is a separate deliverable.
@mrsibe mrsibe added enhancement New feature or request area:provenance Source location, citations, document structure area:retrieval Retrieval quality and evaluation labels Sep 28, 2026
@mrsibe
mrsibe merged commit 0d40f22 into main Sep 28, 2026
4 checks passed
@mrsibe
mrsibe deleted the fix/156-onto-main branch September 28, 2026 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:provenance Source location, citations, document structure area:retrieval Retrieval quality and evaluation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] Citation coverage: mark uncited, invalid and inferred sentences

1 participant