Structured Evidence
Structured evidence is a machine-readable explanation of a verdict. Instead of only a prose message, you get the exact cited-vs-found comparisons the engine performed.
The shape
"evidence": {
"comparisons": [
{
"attribute": "year", // the legal attribute compared
"cited": "2001", // the value as cited (string | null)
"found": "1999", // the value in the resolved authority (string | null)
"match": false // whether the two agree
}
]
}
Iterate comparisons to render an “expected vs. found” view. The mismatches are simply comparisons.filter(c => !c.match).
Which attributes can appear
| Attribute | Compares |
|---|---|
year | Cited decision year vs. the authority’s. |
court | Cited court vs. the deciding court. |
caseName | Cited case name vs. the resolved name. |
page | Cited start page vs. the authority’s start page. |
reporter | Cited reporter vs. the resolved reporter (federal-reporter citations). |
pinpoint | Pinpoint (pin-cite) mismatch, when recorded. |
attribute is an open vocabulary, so tolerate unknown values, as new attributes may be added additively over time.
The one rule that matters: absence ≠ mismatch
Concretely, an attribute is omitted when there was no clean, deterministic comparison to report, for example:
- a partial case-name match (neither a clean agreement nor a clean mismatch);
- a page that could not be deterministically compared;
- a reporter on a non-federal path, where no reporter comparison is performed.
So: read match: false as “the engine compared these and they disagree.” Read no comparison as “the engine did not compare this attribute here,” nothing more.
Why volume is intentionally absent
You will never see attribute: "volume". The engine performs no deterministic volume comparison: a volume never diverges on a resolved record because the lookup is keyed on the full citation. Rather than fabricate a comparison the engine never runs, GhostCite omits it. This is a deliberate contract decision, not a gap.
How to consume comparisons
- Iterate what’s present. Loop
evidence.comparisons; don’t assume a fixed set of attributes. - Show mismatches first.
comparisons.filter(c => !c.match)is your “needs review” list. - Handle
null. Within a comparison,cited/foundare always present but may benull(“compared, value unavailable”), distinct from the whole comparison being absent. - Don’t re-derive verdicts. Evidence explains the
verdict; it never contradicts it. Useverdict.statusfor the headline, evidence for the detail. - Treat absence neutrally. Missing evidence, or a missing attribute, is not a signal by itself.
evidence is optional: it is omitted entirely when no comparison underlies a verdict (for example, a citation that resolved to nothing). Its absence means “no structured comparison available,” never “withheld.”