verify-citation

star 28

Verify that academic citations exist and match the metadata claimed for them, and optionally write verification results into a project summary table. Looks up DOIs against CrossRef, fetches canonical authors/title/year/journal and the abstract via OpenAlex, and reports any mismatch against a BibTeX entry or a free-form DOI. Use to gate every citation `literature-curator` adds, to audit an existing BibTeX file for fabricated or wrong entries, or to retrieve an abstract so the calling agent can judge whether the paper actually supports a given claim.

youngeun1209 By youngeun1209 schedule Updated 5/19/2026

name: verify-citation description: Verify that academic citations exist and match the metadata claimed for them, and optionally write verification results into a project summary table. Looks up DOIs against CrossRef, fetches canonical authors/title/year/journal and the abstract via OpenAlex, and reports any mismatch against a BibTeX entry or a free-form DOI. Use to gate every citation literature-curator adds, to audit an existing BibTeX file for fabricated or wrong entries, or to retrieve an abstract so the calling agent can judge whether the paper actually supports a given claim.

Provide a deterministic, network-based existence + metadata check on academic citations so that no fabricated or mis-cited reference makes it into the manuscript. Returns canonical metadata and the abstract so the calling agent (typically `literature-curator`) can assess claim-fit semantically. Optionally writes the verification verdict into the project's literature summary table so the audit trail lives next to the bibliography. - `literature-curator` is about to add a new entry to the project BibTeX file. - A reviewer / supervisor asks "is this citation real?" or "does this paper actually say X?". - Auditing an existing BibTeX file (e.g. after a co-author imports references from another project). - Resolving a `[CITE: ...]` placeholder — verify the candidate before committing. - Refreshing the `verified_on` / `verify_status` columns of the project summary table. - Only the citation **format** needs fixing (use a BibTeX prettifier, not this). - The user wants to *find* a citation from scratch with no candidate yet — that is `literature-curator`'s WebSearch task; this skill verifies once a candidate exists. - Offline-only environment with no network — skill requires CrossRef/OpenAlex. This skill reads:
Variable Default Purpose
BIB_FILE references.bib Path to project BibTeX. Used when verifying by citekey.
SUMMARY_FILE references.csv Project literature summary table. When --summary-csv is set (or this is configured in CLAUDE.md), verified_on / verify_status are written back per citekey.
CITATION_VERIFY_EMAIL (unset) Polite-pool email for CrossRef/OpenAlex. Strongly recommended — gives a higher rate limit and prioritizes your requests.
CITATION_VERIFY_TIMEOUT 15 Request timeout in seconds.

Resolution order on each invocation:

  1. Command-line flags (highest priority).
  2. Environment variables.
  3. Project CLAUDE.md "Research stack" block — fields BibTeX file, Summary file, CrossRef email.
  4. Defaults above.

If BIB_FILE is not configured on first use, ask the user once and offer to persist it.

Step 1 — Pick the input mode

Four modes:

# Verify a single DOI
python3 verify_citation.py --doi 10.1038/s41586-023-XXXXX-X

# Verify one citekey from the BibTeX file
python3 verify_citation.py --bib references.bib --key smith2023connectome

# Audit the whole BibTeX file
python3 verify_citation.py --bib references.bib

# Audit and also update the project summary table in place
python3 verify_citation.py --bib references.bib --summary-csv references.csv

Optional flags:

  • --claim "<one-line claim>" attaches the claim to the report so downstream logs show what was being supported. The skill does NOT decide whether the abstract supports it — that is the calling agent's call.
  • --json emits structured JSON instead of the human report.

Step 2 — Run the verifier

python3 "$CLAUDE_PLUGIN_ROOT"/skills/verify-citation/verify_citation.py \
    --bib "$BIB_FILE" \
    --summary-csv "$SUMMARY_FILE"

The script:

  1. Parses the requested entry(ies) from the BibTeX file.
  2. Hits CrossRef (api.crossref.org/works/<DOI>) for canonical metadata.
  3. Falls back to a CrossRef title+author search if no DOI is present in the BibTeX.
  4. Hits OpenAlex (api.openalex.org/works/doi:<DOI>) for the abstract.
  5. Compares author / title / year between BibTeX and CrossRef; flags mismatches.
  6. If --summary-csv is set, writes verified_on (today, YYYY-MM-DD) and verify_status to the matching citekey row. Other columns (our_use, paper_says, bucket, cited_sections) are never overwritten.

Step 3 — Read the report

Human report (per entry):

[PASS|MISMATCH|NOT_FOUND] <citekey or DOI>
  DOI:        <doi>          → CrossRef: <found / not found>
  Title:      crossref="..."    match=<true/false>
  Author:     crossref="..." (+N more)   match=<true/false>
  Year:       crossref=YYYY   match=<true/false>
  Abstract (first 500 chars):
    "..."
  Claim:      <if --claim was provided>
  → Read the abstract above and confirm whether it supports the claim.
  Note:       <any flags>

Statuses:

  • PASS — DOI resolves AND title/authors/year all match (case-insensitive, normalized).
  • MISMATCH — found at CrossRef but at least one metadata field disagrees with the BibTeX entry.
  • NOT_FOUND — DOI does not resolve and title+author search returns no plausible match.
  • NOT_VERIFIED — network error, surfaced separately; not treated as a pass.

Step 4 — Caller assesses claim-fit

The script does NOT decide whether the abstract supports the claim — that requires reading. The calling agent reads the abstract from the report and answers the claim-fit question. The skill provides the evidence; the agent provides the judgment.

stdout: human-readable report (one block per entry) — or JSON if --json was passed.

Exit codes:

  • 0 — all entries PASS.
  • 1 — at least one entry MISMATCH or NOT_FOUND.
  • 2 — script error (network down on every retry, malformed BibTeX, missing file, etc.).

When --summary-csv is set:

  • Columns updated: verified_on, verify_status (per-citekey).
  • Columns added if the citekey row does not exist: a new row with citekey, verified_on, verify_status filled and human-curated columns left blank for literature-curator to fill.
  • Columns the skill never touches: our_use, paper_says, bucket, cited_sections, authors, year, title, venue, doi. These belong to the curator.
Symptom Cause Action
urllib.error.URLError / timeout Network unreachable, CrossRef down Retry once; if still failing, report affected entries as NOT_VERIFIED (network) and do NOT mark them PASS
Title matches but DOI does not resolve BibTeX has a typo in DOI Report as MISMATCH; the curator agent fixes the DOI
Author count differs BibTeX truncates with "et al." Soft MISMATCH — flagged in notes but does not necessarily fail (curator decides)
Abstract empty in OpenAlex Publisher does not deposit abstracts Skill still PASSes on metadata; caller must verify claim-fit via manuscript download
Summary file does not exist First run, no summary table yet Skill creates the file with the canonical header row
- `SKILL.md` — this file. - `verify_citation.py` — the verifier. Stdlib-only (`urllib`, `json`, `csv`, `re`). Runnable as a script or importable.
Install via CLI
npx skills add https://github.com/youngeun1209/oh-my-claudecode-research --skill verify-citation
Repository Details
star Stars 28
call_split Forks 7
navigation Branch main
article Path SKILL.md
More from Creator
youngeun1209
youngeun1209 Explore all skills →