citation-crosscheck
Double-blind bibliographic cross-check: one agent extracts each cited entry verbatim from the local .bib, a second independently re-fetches the same paper's record from the web while blind to the .bib, and a third extractor emits a mechanical field-by-field delta to catch dropped/re-ordered authors,…
Install / Use
npx skills add wanshuiyin/Auto-claude-code-research-in-sleep --skill citation-crosscheckInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Data & AnalyticsSupported Platforms
Tags
Our assessment of citation-crosscheck
citation-crosscheck scores 96/100 on our quality scale, 37th of 601 Data & Analytics skills we index (top 7%).
Its SKILL.md is 36 KB long, well organised into 53 sections with 3 code examples: a thorough specification that gives an agent plenty to work with.
With 17,747 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated yesterday, so citation-crosscheck is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
citation-crosscheck compared with similar skills
All 4 of these similar skills score higher than citation-crosscheck; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| citation-crosscheck (this skill)by wanshuiyin | 96 | 17.7k | 1d ago | SKILL.md |
| algorithmic-artby anthropics | 100 | 177.9k | 27d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 27d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 137.2k | 5d ago | SKILL.md |
| ui-ux-pro-maxby nextlevelbuilder | 100 | 137.2k | 5d ago | SKILL.md |
Frequently asked questions
- How do I install citation-crosscheck?
- Run
npx skills add wanshuiyin/Auto-claude-code-research-in-sleep --skill citation-crosscheck. The install tabs above show the steps for each supported agent. - Which AI agents does citation-crosscheck work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is citation-crosscheck safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is citation-crosscheck still maintained?
- The repository was last updated yesterday, so citation-crosscheck is actively maintained.
Skill content
View source on GitHubname: citation-crosscheck description: "Double-blind bibliographic cross-check: one agent extracts each cited entry verbatim from the local .bib, a second independently re-fetches the same paper's record from the web while blind to the .bib, and a third extractor emits a mechanical field-by-field delta to catch dropped/re-ordered authors, wrong years, wrong venues, and bad DOIs/arXiv ids. The main agent (never a shard) assigns the MATCH/MINOR/MISMATCH verdict per reference, and exports a side-by-side spreadsheet. Use when user says "citation crosscheck", "double-blind citation check", "verify bib against scholar", "bib field audit", "引用交叉核对", or before submission when bibliography FIELD accuracy (not just existence) must be certified." argument-hint: "[paper-directory-or-bib-file] [--xlsx <path>] [--cited-only|--all]" allowed-tools: Bash(*), Read, Grep, Glob, Write, Agent, WebFetch, WebSearch
Citation Cross-Check (double-blind bib-vs-web field audit)
🔒 Do not wrap this skill in
/loop,/schedule, orCronCreate. It is verdict-bearing — it emits a per-reference verdict that gates.bibedits (an evidence instrument, not a cross-model acquittal; see the acceptance-gate note in Step 2). Re-running it on a timer adds no signal (the verdict changes only when the bibliography changes). Schedule the external wait that precedes it: bibliography finalized → run once. Seeshared-references/external-cadence.md.
Why this exists (and how it differs from citation-audit)
citation-audit is a single cross-model reviewer that judges three things holistically:
existence, metadata, and context-fit (is the cited paper used for a claim it
actually supports?). This skill does not do context-fit. It does one thing that a
single reviewer cannot do reliably: an adversarial, double-blind, field-level diff
of the local .bib entry against an independently reconstructed record.
The failure mode it targets is the hand-entry error that survives a plausibility read:
a dropped or re-ordered author, a wrong year, a swapped venue, a DOI that
404s. A single reviewer that sees the .bib entry tends to anchor on it and rate it
"looks correct." Two agents that never see each other's output cannot anchor — a
discrepancy only survives if both independent records agree, and the verifier reports
exactly where they diverge.
In practice it catches dropped/re-ordered authors, wrong years, and bad DOIs that a
single-pass audit rated "looks clean" — while NEEDS_WEBCHECK stops it from
false-flagging a legitimate non-arXiv (blog / tech-report) citation as fabricated. Use it
in addition to citation-audit, not instead: citation-audit protects your review
score (context-fit); this protects
against the integrity red flag of a wrong or fabricated reference (existence + fields).
| | citation-audit | citation-crosscheck (this) |
|---|---|---|
| Owns | existence + metadata + context-fit | existence + field accuracy, adversarially |
| Method | one cross-model reviewer | two blind extractors + a mechanical field-diff |
| Reads the .tex claims? | yes | no (bibliographic only) |
| Deliverable | KEEP/FIX/REPLACE/REMOVE per entry | side-by-side .xlsx + MATCH/MINOR/MISMATCH |
| Best at catching | wrong-context citation | dropped/re-ordered author, wrong year/venue/DOI |
Constants
- BLIND = true — the web agent (B) MUST be prompted with only each paper's title +
first author, plus its opaque
dedup_key(a run-local ordinal that carries no bibliographic content), and MUST NOT read the.bibor any repo file. This is the whole point; do not relax it. - SOURCES = arXiv (
/abs/<id>,/bibtex/<id>), DBLP, CrossRef, ACL Anthology, NeurIPS/PMLR proceedings, OpenReview. Report what the fetched page shows; never fabricate a field. - VERDICTS (assigned by the main agent only, in Step 4 — never by a shard) =
MATCH(bibliographically equivalent, cosmetic-only) /MINOR(formatting or a preprint-vs-published venue, no correction required) /MISMATCH(real discrepancy: wrong/missing author, wrong year, wrong venue, wrong id) /NEEDS_WEBCHECK(B could not confirm existence, but the entry is a@misc/blog/tech-report whoseurlB's index-based search structurally cannot see — the main agent must fetch thaturlin Step 4 before any verdict; never downgrade such an entry straight toMISMATCH). - SCOPE = cited-only by default (entries that render in the
.bbl);--allalso covers uncited.bibentries. - OUTPUT =
<paper-dir>/citation_crosscheck_<date>.xlsx(+ the four intermediate JSONs —cx_A_ourbib,cx_B_web,cx_C_fielddiff, and the gate'scx_gate.json— kept for audit).
Workflow
Step 1 — Resolve the citation set (deterministic, main agent)
# Search the paper's own source tree, not the whole repo: bundled author-kit /
# template .tex carry demo \cite{...} that inflate the set. Set PAPER_DIR to the dir of
# the main .tex (\documentclass + \bibliography); recurse (cites often live in
# sections/*.tex); exclude vendored/example dirs.
PAPER_DIR="<dir of the paper's main .tex>"
cd "$PAPER_DIR"
python3 - <<'PY'
import re, pathlib
# Skip vendored/example/template trees: bundled author kits carry demo \cite{...}.
# NOTE: this is a NAME match — a dir you *want* audited must not match (rename it or
# narrow SKIP), e.g. `examples_of_results/` would be skipped.
SKIP = re.compile(r'(?i)(^|/)(.*template.*|.*upstream.*|.*example.*|.*vendor.*)(/|$)')
# Verbatim-ish blocks AND inline \verb|...| / \lstinline are code samples, not citations.
VERB = re.compile(r'\\begin\{(verbatim|lstlisting|minted|Verbatim)\}.*?\\end\{\1\}', re.S)
# The optional arg may itself contain brackets: \lstinline[language={[LaTeX]TeX}]|...|
VERBINLINE = re.compile(r'\\(?:verb|lstinline)\*?'
r'(?:\[(?:[^\[\]]|\[[^\]]*\])*\])?\s*'
r'([^\sA-Za-z])(?:(?!\1).)*\1', re.S)
# url/href/path args may contain a literal % that is NOT a comment. Neutralize them
# BEFORE comment-stripping, or a real \cite later on that line is silently lost.
URLCMD = re.compile(r'\\(?:url|href|path|nolinkurl)\s*\{[^{}]*\}')
COMMENT = re.compile(r'(?m)(?<!\\)%.*$')
# EXPLICIT ALLOWLIST of cite commands. Do NOT build this from a prefix/suffix pattern:
# a Cartesian `(no|paren|auto|...)?cite(s|p|t|...)?` both invents commands (\citecite,
# \parenciteyear -> fake keys from any brace arg) and misses real ones (\footfullcite,
# \volcite, \notecite). Longest-first so \footfullcite wins over \footcite.
# volcite-family: the FIRST brace arg is a volume/page, NOT a cite key.
VOLCITE = {'volcite', 'Volcite', 'pvolcite', 'Pvolcite', 'fvolcite', 'ftvolcite',
'svolcite', 'tvolcite', 'avolcite',
'volcites', 'Volcites', 'pvolcites', 'Pvolcites', 'fvolcites', 'svolcites',
'tvolcites', 'avolcites', 'ftvolcite', 'ftvolcites'}
NAMES = sorted({
# natbib / LaTeX core (capitalized variants are real natbib commands)
'cite', 'Cite', 'citep', 'citet', 'citealp', 'citealt', 'citenum', 'citeyear', 'citeyearpar',
'citeauthor', 'citefullauthor', 'Citep', 'Citet', 'Citealp', 'Citealt', 'Citeauthor',
# biblatex singular + plural
'parencite', 'Parencite', 'footcite', 'footcitetext', 'footcitetexts', 'textcite',
'Textcite', 'smartcite', 'Smartcite', 'supercite', 'autocite', 'Autocite', 'fullcite',
'footfullcite', 'notecite', 'Notecite', 'pnotecite', 'Pnotecite', 'fnotecite',
'citetitle', 'citeurl', 'citedate', 'autocites', 'parencites', 'textcites',
'smartcites', 'supercites', 'footcites', 'cites', 'Cites', 'nocite', 'nocites',
# aliases + field/list forms + bibentry — real biblatex/natbib families
'citetalias', 'citepalias', 'Citetalias', 'Citepalias', 'citefield', 'citelist',
'bibentry', 'fullciter',
*VOLCITE,
}, key=len, reverse=True)
# (?![A-Za-z]) stops \cite matching the \citeXYZ of an unknown command; the trailing run
# accepts any mix of [opt] and {grp} so \cites{k1}[note]{k2} yields BOTH keys.
CITE = re.compile(r'\\(?:' + '|'.join(map(re.escape, NAMES)) + r')\*?(?![A-Za-z])'
r'((?:\s*(?:\[[^\]]*\]|\{(?:[^{}]|\{[^{}]*\})*\}))+)', re.S)
# Strip [optional] args BEFORE reading brace groups, or a braced note like
# \cite[see {Smith} p.3]{k} contributes 'Smith' as a phantom key.
OPTARG = re.compile(r'\[[^\]]*\]', re.S)
GROUP = re.compile(r'\{((?:[^{}]|\{[^{}]*\})*)\}', re.S)
CMDNAME = re.compile(r'\\([A-Za-z]+)')
# \addbibresource[opts]{x.bib} takes an optional arg; \bibliography{a,b} may list several.
BIBRES = re.compile(r'\\(?:bibliography|addbibresource)\s*(?:\[[^\]]*\])?\{([^}]+)\}')
keys, bibs, nocite_all = set(), [], False
for p in sorted(pathlib.Path('.').rglob('*.tex')):
if SKIP.search(str(p.parent)):
continue
src = p.read_text(errors='replace')
src = VERB.sub(' ', src)
src = VERBINLINE.sub(' ', src)
src = URLCMD.sub(' ', src)
src = COMMENT.sub('', src)
for res in BIBRES.findall(src):
bibs += [r.strip() for r in res.split(',') if r.strip()]
for m in CITE.finditer(src):
raw_cmd = CMDNAME.match(m.group(0)).group(1)
cmd = raw_cmd.lower()
grps = GROUP.findall(OPTARG.sub(' ', m.group(1)))
if raw_cmd in VOLCITE and len(grps) > 1:
# volcite takes {volume}{key}; the PLURAL volcites alternates
# {vol}{key}{vol}{key}... — so keep the odd-indexed args, not just grps[1:],
# or the second volume number is harvested as a phantom key.
grps = grps[1::2]
elif raw_cmd in ('citefield', 'Citefield', 'citelist', 'Citelist',
'bibentry') and len(grps) > 1:
# These commands take a single key(s) arg. If a stray second brace group
# follows (a defensive read of an ambiguous source), do not harvest it as a
# phantom key ('\citelist{k}{publisher}' -> just 'k', not '{k, publisher}').
grps = grps[:1]
for grp in grps:
toks = [''.join(g.split()) for g in grp.split(',')]
# \nocite{*} AND \nocite{*,named}: the wildcard renders EVERY bib entry.
if cmd.startswith('nocite') and '*' in toks:
nocite_all = True # see the NOCITE_ALL note below
for k in toks:
if k and k != '*':
keys.add(k)
print(f"BIB_RESOURCE={bibs[0] if bibs else '(none found - use the fallback below)'}")
print(f"BIB_RESOURCES_ALL={bibs}")
print(f"NOCITE_ALL={nocite_all}")
print(f"CITED_KEY_COUNT={len(keys)}")
import pathlib
# Persist the harvest so the shell can read it back deterministically (the heredoc only
# PRINTS to stdout; it cannot set a parent-shell variable).
pathlib.Path('/tmp/cx_cited_keys.txt').write_text('\n'.join(sorted(keys)))
pathlib.Path('/tmp/cx_cited_count.txt').write_text(str(len(keys)))
print('\n'.join(sorted(keys)))
PY
# Set $CITED_KEY_COUNT as a REAL shell variable (Step 3.5 passes it as --expect): the
# heredoc above only prints it, so read it back from the file the harvest just wrote.
CITED_KEY_COUNT=$(cat /tmp/cx_cited_count.txt)
Cross-check against a compiled main.bbl by KEY SET, not count: a count match with a
substituted key still hides a harvest miss (drop one real cite, gain one stray → same count).
Extract the rendered keys and diff the sets:
# \bibitem[label]{key} (natbib/plain) OR \entry{key}{type}{} (biblatex) — key is the first
# brace group either way. Empty diff = harvest and .bbl agree.
grep -oE '\\(bibitem|entry)\*?(\[[^]]*\])?\{[^}]+\}' main.bbl 2>/dev/null \
| sed -E 's/.*\{([^}]+)\}$/\1/' | sort -u > /tmp/cx_bbl_keys.txt
comm -3 <(sort -u /tmp/cx_cited_keys.txt) /tmp/cx_bbl_keys.txt # any output ⇒ investigate
**The .bbl cross-check is conditional — an uncompiled submission has none. When absent,
confirm `C
Truncated for display — read the full file on GitHub.
Related Skills
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
137.2kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
ui-ux-pro-max
137.2kUI/UX design intelligence for web, mobile, and desktop. This skill should be used when designing, building, reviewing, or fixing interfaces, including pages, components, design systems, accessibility, interaction, responsive layout, typography, color, charts, and stack-specific UI implementation.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
