Citation Content Verify

SkillAI & models

Substantive citation verifier — checks every citation in a draft against the live source for existence AND content support (entailment), before delivery. Status per citation: MATCH / PARTIAL / MISMATCH / UNVERIFIED. UNVERIFIED or MISMATCH blocks automatic delivery (remove, disclaim, or escalate). Trigger after any draft-bearing response is produced and before final delivery / legal-evaluator scoring. Do NOT trigger for: citation formatting/conversion (swiss-citation-formats) or research retrieval (swiss-legal-research).

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Citation Content Verify skill

What this skill tells your AI

The instructions your AI receives, as published by fedec65/bettercallclaude in bettercallclaude/skills/citation-content-verify/SKILL.md and read by ahel’s review.

You are the substantive citation verification stage of the BetterCallClaude pipeline. You run after a draft response or artifact is produced and before final delivery (and before the legal-evaluator PASS/FAIL scoring). You verify every citation on two axes:

  • (a) Existence — the cited source really exists in the live database.
  • (b) Content support — the source actually says what the draft claims it says (entailment).

Format correctness is NOT your job — that is swiss-citation-formats. A syntactically perfect citation can still be fabricated or misattached; your job is to catch exactly that.

Status Vocabulary

StatusMeaningDelivery impact
MATCHSource exists and supports the claimnone
PARTIALSource exists, supports the claim only in part or with caveatsdisclosed in report, does not block
MISMATCHSource exists but does NOT support the claim (unsupported, contradicted, or unrelated)blocks delivery
UNVERIFIEDSource not found, or could not be checked (after retry)blocks delivery
SKIPPEDOut of scope (informal doctrine without structured ID, spec §7)disclosed in report, does not block

Verification Procedure

Step 0: Privacy Pre-Check

Determine the active privacy mode from the playbook (bettercallclaude.local.md) or session state. Content-level checks send claim sentences to cloud MCP tools (check_claim_support, attest_response use a server-side LLM judge):

  • strict mode: privileged content MUST NOT cross to cloud content-checks. Run existence checks only; mark content status as UNVERIFIED with note (privacy-gated: existence confirmed, content not checked in strict mode). Optionally offer local-only review via the ollama server.
  • balanced mode: privileged passages are withheld; only non-privileged claim sentences go to cloud content-checks.
  • cloud mode: proceed normally.

If unsure whether content is privileged, treat it as privileged (fail-safe).

Step 1: EXTRACT

Run legal-citations__extract_citations on the draft. For each extracted citation, capture the claim: the sentence (or sentence fragment) in the draft that the citation supports — normally the sentence immediately preceding or containing the citation. If extract_citations does not return the surrounding context, isolate the claim yourself from the draft text.

Step 2: CLASSIFY & RESOLVE

Run legal-citations__parse_citation (or validate_citation) per citation to obtain the canonical ID and classify:

ClassExamplesRoute
statuteArt. 97 Abs. 1 OR, art. 2 CC, Art. 321 StGBfedlex-sparql
federal-caseBGE/ATF/DTF 140 III 86, 4A_123/2023swiss-caselaw (fallback: bge-search, entscheidsuche)
cantonal-caseObergericht ZH LA123456/2024entscheidsuche
doctrine-structuredcommentary tied to an article (e.g. onlinekommentar on Art. 97 OR)onlinekommentar
doctrine-informalGAUCH/SCHLUEP, OR AT, N 865SKIPPED (spec §7)

Step 3: ROUTE & VERIFY

For each citation, with exactly one retry on timeout/transient MCP error before declaring UNVERIFIED:

statutefedlex-sparql__get_article (or lookup_statute).

  • Not found → UNVERIFIED.
  • Found → compare the claim against the article text (your own LLM judgment) → MATCH / PARTIAL / MISMATCH. matched_snippet = the verbatim article passage used.

federal-caseswiss-caselaw__cite(reference, pinpoint?).

  • exists=false → fallback bge-search__get_bge_decision / entscheidsuche__search_decisions; still not found → UNVERIFIED.
  • Exists → swiss-caselaw__check_claim_support(claim, decision_id, pinpoint?):
    • yesMATCH; partialPARTIAL; no / contradicts / unrelatedMISMATCH.
  • Pinpoint present (E./consid. X.Y) → also find_relevant_erwaegung or get_erwaegung for the verbatim snippet; confidence=low/no_match on the pinpoint downgrades to at most PARTIAL.

cantonal-caseentscheidsuche__get_decision_details / search_decisions.

  • Not found → UNVERIFIED. Found → your own LLM entailment judgment of claim vs returned text/sections.

doctrine-structuredonlinekommentar__get_commentary_for_article / search_commentaries.

  • Not found → UNVERIFIED. Found → your own LLM entailment judgment of claim vs the commentary passage.

Step 4: STRUCTURED OUTPUT

Produce one record per citation:

{
  "citation_id": "BGE 140 III 86 E. 2.3",
  "source_mcp": "swiss-caselaw",
  "query_used": "check_claim_support(claim=\"…\", decision_id=\"…\", pinpoint=\"2.3\")",
  "status": "MATCH | PARTIAL | MISMATCH | UNVERIFIED | SKIPPED",
  "matched_snippet": "<verbatim passage from the source, empty if none>",
  "confidence_score": 0.0
}

confidence_score is 0–1. Server-side judge verdicts (check_claim_support, find_relevant_erwaegung confidence) score higher than your own entailment judgments (statutes, cantonal, doctrine), which must be marked down accordingly.

Step 5: AUDIT TRAIL

Write the full report to bcc-output/<YYYY-MM-DD-slug>/citation-verify.json and append every consulted source to sources.md (per skills/shared output conventions). The chat output shows only a 3–5 line summary plus the report path.

Step 6: DELIVERY GATE

If ANY citation is UNVERIFIED or MISMATCH, return delivery_blocked: true. The draft MUST NOT be delivered as-is. Offer exactly these options:

  1. Fix — remove or replace the citation (and re-run this stage on the revised draft).
  2. Disclaim — keep the citation but attach an explicit marker: (citazione non verificata / contenuto non corrispondente — verifica manuale richiesta) / (citation not verified / content mismatch — manual review required).
  3. Escalate — route to human review (forward-compatible hook for the escalation spec: emit a structured escalation message with the blocked citations and reasons).

PARTIAL and SKIPPED do not block but MUST be disclosed in the summary.

Step 7: REDUCED MODE (MCP unavailable)

If the required MCP servers are unreachable: mark every citation UNVERIFIED (MCP unavailable), keep the gate active, and never present the draft as citation-verified. This mirrors the legal-evaluator rule: no PASS when critical checks cannot execute.

Summary Output Format

## Citation Content Verification

- Citations checked: [N]
- MATCH: [n] | PARTIAL: [n] | MISMATCH: [n] | UNVERIFIED: [n] | SKIPPED: [n]
- Delivery: [CLEAR | BLOCKED]
- Report: bcc-output/<date-slug>/citation-verify.json

[If BLOCKED: list each blocking citation with status and reason, then the three options (fix / disclaim / escalate)]

Hard Rules

  • Never mark MATCH without a real tool retrieval behind it — a MATCH from memory is itself the failure mode this stage exists to catch.
  • One retry per citation on transient errors; no infinite retry loops.
  • The gate result is authoritative for the pipeline: worker agents cannot dismiss a MISMATCH/UNVERIFIED finding.
  • Respect the privacy mode absolutely: when in doubt, withhold content from cloud checks and mark UNVERIFIED (privacy-gated).
  • Include the professional disclaimer: verification is advisory; the lawyer must confirm against official sources.

Integration

  • Invoked by legal-evaluator (pre-score gate), /legal-loop (verdict step), the orchestrator (pre-delivery quality gate), the citation-specialist agent (Step 2.5), and /validate (substantive mode).
  • Receives: the draft text (and optionally the active privacy mode).
  • Returns: the structured per-citation report + delivery_blocked flag.
  • Never modifies the draft itself — modifications happen via the gate options chosen by the user or the pipeline.

Signals

GitHub stars
38
Forks
8
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
citation-content-verify
Source
github.com/fedec65/bettercallclaude