Paste an AI-drafted legal filing. cite-guard extracts every case citation, checks each one against a known-cases index, and returns a single hallucination-risk score plus a per-citation verdict: verified, unverified, or fabricated.
One number tells you whether a brief is safe to file. Live demo: citeguard.dashable.dev
AI drafting tools invent citations that look real. Courts have sanctioned lawyers for filing them. "We verify citations" is a claim every legal-AI vendor makes; cite-guard turns it into a number a buyer can watch run.
Each citation lands in one of three states:
- verified — the citation resolves to a case in the index, and the case name (when given) matches.
- unverified — the citation is well-formed but is not in this corpus. This is not an accusation. It means "could not be confirmed here," nothing more.
- fabricated — the citation is provably inconsistent. cite-guard asserts this
only when it can prove it, never from mere absence. Three provable signals:
- impossible volume — the reporter is real but the volume exceeds the highest
volume ever published (e.g.
947 U.S. 1188; U.S. Reports stops around 610). - name/cite mismatch — the index holds that exact citation for a different case than the one named.
- zero volume or page — structurally invalid.
- impossible volume — the reporter is real but the volume exceeds the highest
volume ever published (e.g.
The composite is fabrication-dominant and fabrication-gated:
raw = round( 100 * (1.0·fabricated + 0.3·unverified) / total ) // 0..100
band = RED if any fabricated citation exists (regardless of raw)
AMBER if >= 34% of citations are unverified
GREEN otherwise
One provably fake citation pins the verdict to RED even when the numeric score is low. A clean brief whose citations simply are not in the sample corpus scores honestly as unverified, not red.
One scorer, two entry points, no drift:
lib/extract.ts— citation regex + case-name capturelib/score.ts— classification (the three-state logic) + compositelib/analyze.ts— composes extract → classify → compositelib/check.ts— CLI; reads the sqlite index (data/cases.db)build.ts— bundles the same scorer (via esbuild) into one self-containedout/index.htmlthat scores pasted text client-side
The browser demo and the CLI run the identical scorer.
Requires Node 24+ (uses native TypeScript execution and node:sqlite).
npm install # one dev dependency: esbuild
npm run seed # build data/index.json + data/cases.db
npm run build # build out/index.html
npm test # 11 scorer/extractor tests
# score a filing from the CLI
node lib/check.ts data/sample-brief.txt
node lib/check.ts my-brief.txt --json
cat brief.txt | node lib/check.tsOptional enrichment from CourtListener (off the critical path; failures only warn):
node data/seed.ts --courtlistenerThe extractor and scorer (lib/) are MIT. The jurisdiction corpus and
reporter-validity weighting under data/ are proprietary and not licensed for
redistribution. Own the verification layer; open-source the plumbing.
cite-guard confirms citations against its index. It is not legal advice. Always confirm citations against an authoritative reporter before filing.
