Install
openclaw skills install @workloftai/cite-checkConfirm every citation in a draft is real before it ships — extract each URL and arXiv ID and fetch it to prove it resolves (phase 1), then optionally check the source actually backs the claim next to it via a local NLI model (phase 2). Exit non-zero on any failure so it drops into a publish pipeline as a blocking gate.
openclaw skills install @workloftai/cite-checkAgents fabricate citations — a plausible-looking link or an arXiv ID that does not exist, dropped into otherwise good copy that nobody checks. A rule a human has to remember ("verify every URL") is not a guard. This is the guard.
Two phases:
{baseDir}/cite_check.py) — the resolve check. Is the source real?{baseDir}/claim_check.py) — the support check. Does the source
actually back the claim beside it? Catches misattribution.Phase 1 needs only httpx (pip install httpx). Phase 2 additionally needs
beautifulsoup4, pymupdf, and a local NLI cross-encoder (via
sentence-transformers/transformers) — heavier, first run downloads the model.
Run it as a blocking gate before publishing anything with citations — a research note, a post, an email. Phase 1 catches dead links and fabricated arXiv IDs; phase 2 catches a real source cited for something it never says.
python3 {baseDir}/cite_check.py draft.md # check a file
cat draft.md | python3 {baseDir}/cite_check.py # stdin
python3 {baseDir}/cite_check.py draft.md --json # machine-readable
python3 {baseDir}/cite_check.py draft.md --strict # also fail if NO citations
Exit 0 when every citation resolves, 1 when any fail — drops into a pipeline:
python3 {baseDir}/cite_check.py "$DRAFT" || { echo "unverified citation"; exit 1; }
URLs: HEAD then streamed-GET fallback, status < 400 passes, redirects followed.
arXiv IDs: looked up against the official arXiv API (an abs/<id> page can 200
for a non-existent paper), so a fabricated ID fails.
python3 {baseDir}/claim_check.py draft.md
python3 {baseDir}/claim_check.py draft.md --json
Decomposes the draft into (claim, citation) pairs, fetches the real source text
(arXiv full text/abstract; HTML via BeautifulSoup; PDF via pymupdf), scores
claim-vs-source with a local NLI cross-encoder. Verdicts: SUPPORTED / PARTLY /
UNSUPPORTED / UNVERIFIABLE. Exit 1 if anything is not SUPPORTED. Swap the model
with CITE_CHECK_NLI_MODEL.
{baseDir}/cite_check.py / {baseDir}/claim_check.py.