citegate
Citation integrity as a CI gate. citegate verifies every entry in your BibTeX files against Crossref and OpenAlex, then fails your build when a reference is fabricated, wrong, or retracted.
LLM writing assistants fabricate plausible-looking references, and even careful humans cite papers that later get retracted. Existing checkers are interactive tools you have to remember to run. citegate is the piece that belongs in your repository instead: a GitHub Action, a pre-commit hook, and a weekly monitor that opens an issue the day a paper you cite is retracted.
OK he2016deep
NOT FOUND fabricated2023 (best title similarity 0.42)
- no record with a similar title in Crossref or OpenAlex — possibly a fabricated reference
RETRACTED wakefield1998retracted
- OpenAlex marks this work as retracted
- Crossref/Retraction Watch records: retraction
citegate: checked 3 entries — 1 verified, 1 retracted, 1 not-found
What it checks
| Verdict | Meaning |
|---|---|
verified |
The entry matches a real indexed work (title, year, authors agree). |
not-found |
No similar record exists in Crossref or OpenAlex. Likely fabricated. |
retracted |
The cited work is retracted or withdrawn, per OpenAlex and the Retraction Watch data in Crossref. |
mismatch |
A real work exists, but the year, title, or authors in your entry disagree with the index. |
unverifiable |
Websites, standards, and other entries without a DOI that scholarly indexes do not cover. Never fails the build. |
error |
A source API was unreachable. |
Entries with a DOI are resolved directly and their metadata compared field by field. Entries without a DOI are matched by fuzzy bibliographic search across both indexes; strong matches also get a suggestion with the DOI you should add.
Quick start
pip install citegate # or: pipx install citegate
citegate paper/references.bib --mailto you@example.edu
--mailto is optional but recommended: it identifies you to the APIs and places you in Crossref's polite pool. The exit code is non-zero when any not-found or retracted entry appears (configurable with --fail-on not-found,retracted,mismatch), so the same command works locally and in CI. Add --json report.json for machine-readable output, --cache to skip unchanged entries on repeated runs, and --workers N to tune lookup concurrency (default 4).
GitHub Action
name: References
on: [push, pull_request]
jobs:
citegate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chrisyangsong/citegate@main
with:
files: '**/*.bib'
mailto: 'you@example.edu'
Failures show up as inline annotations and a job-summary table listing exactly which entries are suspect and why.
Retraction monitoring
A bibliography that verified cleanly last month can go bad without you touching it: about one in 500 published papers is eventually retracted, and citing one in a submission is an avoidable reviewer complaint. Copy examples/retraction-monitor.yml into .github/workflows/ and citegate re-verifies your references every Monday, opening an issue in your repository when a cited paper is retracted or stops resolving.
pre-commit hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/chrisyangsong/citegate
rev: v0.2.0
hooks:
- id: citegate
Relation to other tools
Several good interactive checkers exist, including refchecker and hallucinator for auditing a finished paper or PDF, and browser tools like BibTeX Verifier. citegate covers the other half of the problem: it lives in the repository with your .bib files, runs automatically on every push, and keeps watching after you stop looking. If you want a one-off deep audit of a PDF, use those tools; if you want your references checked continuously, use citegate.
Design notes
- Sources: Crossref (REST API, polite pool) and OpenAlex. Retraction status is the union of OpenAlex's
is_retractedflag and Crossref update records, which include the Retraction Watch database. - Matching is deliberately conservative:
@miscand other non-indexed entry types without DOIs are skipped rather than flagged, and a one-year slack is allowed on years (print vs online dates). False alarms are the fastest way to get a checker removed from CI. - No LLMs are involved in verification; every verdict is traceable to an index record.
Roadmap
- DOCX/PDF reference-list extraction (currently BibTeX only)
- arXiv and DBLP as additional sources
- An
--only retractionsfast mode for high-frequency monitoring
Issues and pull requests are welcome.
License
MIT © 2026 Yang Song. Not affiliated with Crossref, OpenAlex, or Retraction Watch; please respect their API terms.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file citegate-0.2.0.tar.gz.
File metadata
- Download URL: citegate-0.2.0.tar.gz
- Upload date:
- Size: 18.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c0950957bec3fb1adb48c4001d4dd5214639e10abfbbdecad8ef7adf819fd14
|
|
| MD5 |
7e7333669b08126af87da3434094ec9a
|
|
| BLAKE2b-256 |
0e9171ccb6763c6d22c24fdfe8d822a831b975f2e942bb582e04a5efa6e27a58
|
Provenance
The following attestation bundles were made for citegate-0.2.0.tar.gz:
Publisher:
publish.yml on chrisyangsong/citegate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
citegate-0.2.0.tar.gz -
Subject digest:
4c0950957bec3fb1adb48c4001d4dd5214639e10abfbbdecad8ef7adf819fd14 - Sigstore transparency entry: 2426527942
- Sigstore integration time:
-
Permalink:
chrisyangsong/citegate@05413cdae03d13e8fdca74fa5b938a69b8bab771 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/chrisyangsong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@05413cdae03d13e8fdca74fa5b938a69b8bab771 -
Trigger Event:
release
-
Statement type:
File details
Details for the file citegate-0.2.0-py3-none-any.whl.
File metadata
- Download URL: citegate-0.2.0-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f01427cb466253e95d821f594e70f87cb03de10141ecd468f35c33ad1a376d7
|
|
| MD5 |
6e26c5d97184f18ca97a0bc35f04c094
|
|
| BLAKE2b-256 |
df176ab21b211cf16d4560047a40f8a2200736957473751fe87b4176e2a7bfa8
|
Provenance
The following attestation bundles were made for citegate-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on chrisyangsong/citegate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
citegate-0.2.0-py3-none-any.whl -
Subject digest:
6f01427cb466253e95d821f594e70f87cb03de10141ecd468f35c33ad1a376d7 - Sigstore transparency entry: 2426528161
- Sigstore integration time:
-
Permalink:
chrisyangsong/citegate@05413cdae03d13e8fdca74fa5b938a69b8bab771 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/chrisyangsong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@05413cdae03d13e8fdca74fa5b938a69b8bab771 -
Trigger Event:
release
-
Statement type: