How to Build Fail-Closed Citation Verification
Developer Guides

How Do You Build a Fail-Closed Citation Verification Pipeline?

DocuShell TeamJuly 6, 202617 min read

Direct answer

Build a fail-closed citation verification pipeline by placing a mandatory release gate between answer generation and user delivery. The gate must release citation-dependent claims only when required source, fingerprint, locator, evidence, schema, and policy checks produce an understood passing result. Missing reports, unknown statuses, stale evidence, mismatches, timeouts, malformed output, and verifier failures must never default to approval.

Fail-closed does not require showing a generic error for every defect. Safe outcomes include a verified partial answer, an explicit abstention, a review task, or a bounded retry. What it forbids is bypassing the gate because verification was inconvenient or unavailable.

The NIST glossary defines fail secure as terminating functions in a way that prevents loss of secure state when failure occurs or is detected. In RAG, the protected state is “unverified citation-dependent claims are not released.”

Define the protected invariant

Write the invariant before code:

No material citation-dependent claim may reach an unauthorized user-visible
or machine-consumable output unless every mandatory release check for that
claim completed under an approved contract and passed.

This applies to:

  • chat responses;
  • exported reports;
  • emails and notifications;
  • API responses;
  • agent tool outputs;
  • downstream database writes;
  • summaries cached for later reuse.

If one channel bypasses the gate, the system is not fail-closed.

The pipeline architecture

authorized request
   -> governed source selection
   -> retrieval with provenance
   -> structured answer + atomic claims + citations
   -> citation request schema validation
   -> deterministic Ethos verification
   -> calculations and semantic policy
   -> claim-level release decision
   -> final / partial / review / abstain / block

The raw model answer should not be streamed directly to the end user when mandatory verification happens afterward. Buffer it as an untrusted candidate, or stream only content classes that policy allows before verification.

Step 1: classify outputs by verification requirement

Define content classes:

Output class Example Default gate
Source fact “The policy limit is $1,200” Citation grounding required
Calculation “Growth was 18.1%” Input grounding plus recomputation
Synthesis “The transaction is permitted” All evidence plus semantic/policy review
User-provided restatement “You asked about travel” Schema and privacy policy
Safety or system message “I cannot verify the source” Approved deterministic template

Never let the model classify its own unsupported claim as exempt without validation.

Step 2: validate the generated answer contract

Require:

  • unique answer and claim IDs;
  • claim text and type;
  • evidence references for source-dependent claims;
  • calculation dependencies;
  • no unknown fields when the schema is strict;
  • bounded lengths and valid encodings;
  • source IDs resolved through a trusted map.

Malformed output is a candidate-generation failure. Retry generation under a bounded policy or abstain; do not pass the raw prose around the verifier.

Step 3: select and authorize the source before verification

The application must:

  • select the authoritative source revision;
  • enforce tenant and resource authorization;
  • resolve model-returned IDs through controlled mappings;
  • verify that source artifacts and citations belong to the same request scope;
  • prevent arbitrary file paths or URLs;
  • capture source-set and policy identity.

Ethos verifies evidence against the GroundingSource it receives. It does not decide whether the application selected the correct corporate, legal, clinical, or policy authority.

Step 4: separate evidence verdicts from infrastructure failures

These categories must not share one false value.

Category Examples Release behavior
Grounding pass Required checks grounded; source fresh Continue
Grounding rejection Mismatch, not found, stale, unsupported Block affected claim
Capability limitation Missing table, fingerprint, spans, or coordinates Review or stronger source
Invalid request Malformed citation schema or locator Reject candidate
Infrastructure failure Missing CLI, timeout, I/O, malformed report Abstain or bounded retry
Unknown contract New schema version or status Block until supported

An infrastructure failure says “no trustworthy verdict was produced.” It does not say “citation failed,” and it certainly does not say “citation passed.”

Step 5: call Ethos with explicit error handling

The Python wrapper returns JSON reports for completed verification and raises structured exceptions for command or timeout failures. When fail_on_ungrounded=True, CLI exit 1 with JSON is a completed negative verification verdict, not a process crash.

from dataclasses import dataclass
from pathlib import Path
from typing import Literal, Optional

from ethos_pdf import (
    EthosCli,
    EthosCommandError,
    EthosNotFoundError,
    EthosOutputError,
    EthosTimeoutError,
    proof_summary,
)


@dataclass(frozen=True)
class GateResult:
    state: Literal["pass", "reject", "infrastructure_failure"]
    reason: str
    report: Optional[dict]


def run_grounding_gate(
    *,
    binary: str,
    source: Path,
    citations: Path,
) -> GateResult:
    verifier = EthosCli(binary=binary)
    try:
        report = verifier.verify(
            source=source,
            citations=citations,
            fail_on_ungrounded=True,
            output_format="json",
            timeout=30,
        )
    except (
        EthosNotFoundError,
        EthosTimeoutError,
        EthosOutputError,
        EthosCommandError,
    ) as exc:
        return GateResult(
            state="infrastructure_failure",
            reason=type(exc).__name__,
            report=None,
        )

    summary = proof_summary(report)
    if summary["request_certified"]:
        return GateResult(state="pass", reason="request_certified", report=report)
    return GateResult(
        state="reject",
        reason=summary["proof_status"],
        report=report,
    )

The release caller must handle every state explicitly. Store the completed canonical report even when the outcome is negative. For infrastructure failures, retain privacy-safe diagnostics and request identity without leaking source content.

Step 6: make the release switch exhaustive

def final_action(result: GateResult) -> str:
    if result.state == "pass":
        return "continue_to_semantic_and_policy_checks"
    if result.state == "reject":
        return "block_or_build_verified_partial"
    if result.state == "infrastructure_failure":
        return "abstain_or_route_to_review"
    raise RuntimeError(f"Unhandled gate state: {result.state!r}")

Unknown states raise. They do not fall through to release.

In TypeScript, use a discriminated union and an exhaustive never check. In any language, avoid defaults such as allow = report?.success ?? true.

Step 7: add bounded retries without bypass

Retry only failures likely to be transient:

  • worker unavailable;
  • temporary filesystem or service error;
  • bounded timeout under known load;
  • idempotent artifact read.

Do not retry semantic mismatches, stale fingerprints, unsupported claims, or malformed citation requests as though randomness might produce a pass.

Retry rules should specify:

  • maximum attempts;
  • total request deadline;
  • idempotency key;
  • backoff and jitter;
  • artifact immutability across attempts;
  • final abstention or review action;
  • metrics and alerting.

A circuit breaker may protect infrastructure, but its open state must not bypass verification. It should move requests to abstention, queue, or review.

Step 8: support safe partial answers

A partial answer is allowed only when:

  • reusable grounded checks exist;
  • source fingerprint is not stale;
  • released claims are relevant source facts;
  • dependencies and calculations pass;
  • removed claims do not make the remaining answer misleading;
  • policy allows partial release;
  • the user sees a clear partial-status disclosure.

The partially verified answer guide provides the claim-selection policy. Build final text from approved claim IDs rather than deleting sentences from raw prose.

Step 9: define safe fallback copy

Use deterministic templates:

  • No evidence: “The available sources do not support an answer.”
  • Verifier unavailable: “I could not verify the cited evidence, so I am not returning a source-dependent answer.”
  • Partial: “The following facts were verified; the remaining part could not be confirmed.”
  • Review required: “The evidence requires authorized review before this conclusion can be shown.”
  • Stale source: “The citation belongs to another source version. The answer must be regenerated.”

Do not ask the model to improvise the fallback after verification fails. It may restate the blocked claim.

Step 10: secure every output path

Audit:

  • streaming tokens;
  • websocket events;
  • server logs;
  • traces and metrics;
  • error pages;
  • cached responses;
  • exports and webhooks;
  • agent memory;
  • notification systems;
  • reviewer queues.

The unverified draft may contain sensitive or unsupported content. Restrict it like any other untrusted artifact.

Step 11: set timeout and availability budgets

Verification belongs in the latency budget. Measure:

  • p50, p95, and p99 verification latency;
  • timeout rate;
  • queue time;
  • report size;
  • failure rate by source and claim kind;
  • partial-answer and abstention rate;
  • reviewer backlog;
  • retry effectiveness.

Do not increase the timeout indefinitely to hide capacity problems. Size workers, isolate expensive crop rendering, cap document and citation complexity, and alert before availability pressure becomes a broad abstention incident.

Step 12: preserve audit evidence

Retain:

  • request and answer candidate IDs;
  • source-set and fingerprint identity;
  • citation request;
  • canonical verification report or infrastructure-error envelope;
  • proof summary;
  • semantic and calculation results;
  • release-policy version;
  • final action and user-facing copy;
  • retries, overrides, and reviewer actions.

The RAG verification report guide defines the canonical evidence fields.

Adversarial test matrix

Failure Expected safe behavior
Citation mismatch Block affected claim
Fabricated evidence ID Not-found rejection
Stale fingerprint Block all reuse from stale report
Table request on text-only source Capability review, not pass
Empty checks Request not certified
Unsupported claim kind Block or review
Missing verifier binary Infrastructure abstention
Verifier timeout Bounded retry, then abstention
Malformed JSON report Infrastructure abstention
Unknown schema version Block until consumer supports it
Circuit breaker open Queue, review, or abstain; never bypass
Raw-answer streaming enabled Test must detect pre-gate disclosure
Partial answer loses a material exception Abstain or review

Test recovery too. After the verifier returns, queued requests must still use current source fingerprints and authorization.

Operational anti-patterns

Fail open after a timeout

This releases the riskiest answers when the control is least available.

Treat missing report as zero findings

No report means no completed verification, not no defects.

Catch every exception and return the model draft

This turns error handling into a verification bypass.

Trust a cached positive report after source change

Cache keys must include source and verification contract identity.

Retry until a probabilistic judge passes

Repeated sampling is not deterministic verification and can select a lucky verdict.

The definitive verdict

A fail-closed citation pipeline protects one invariant: unverified source-dependent claims do not escape. Enforce that invariant across generation, streaming, APIs, caches, logs, and downstream automation. Distinguish completed evidence rejection from capability limitation and infrastructure failure, and make every state lead to an explicit safe action.

Use Ethos for structured deterministic grounding reports, application code for exhaustive release switching, bounded retries for transient infrastructure, and transparent partial or abstention responses for users. The pipeline is fail-closed only when the unavailable verifier is treated as a reason to withhold claims—not a reason to trust them.

Primary keyword: fail-closed citation verification Optimized meta title: How to Build Fail-Closed Citation Verification Optimized meta description: Build a fail-closed RAG citation pipeline that blocks stale, mismatched, unsupported, timed-out, and unverifiable claims before release. Proposed URL slug: how-do-you-build-a-fail-closed-citation-verification-pipeline

Frequently Asked Questions

It is a release policy that withholds citation-dependent claims whenever required evidence checks do not pass or the verification system cannot produce a trustworthy verdict.
Yes, when citation verification is mandatory. A timeout is an infrastructure failure, not proof that citations are valid, so the system should abstain, retry safely within policy, or route to review.
Yes, if independently useful claims have reusable verified evidence and removing failed claims cannot mislead. The response must disclose that it is partial.
Ethos returns structured reports for grounding outcomes and distinct exceptions or exit behavior for processing failures, allowing applications to separate evidence rejection from infrastructure failure.

Free Tool

Hallucination Index

Compare model factuality signals and estimate workflow hallucination risk.

Try Hallucination Index
fail-closed citation verificationRAG release gatecitation verification pipelineRAG safetydeterministic verificationEthos
D

DocuShell Team

The DocuShell editorial group writes and maintains guides for everyday PDF workflows, with updates made when tool behavior or documented limits change. See our editorial standards for the process behind each article.

Focus: RAG release architecture, fail-closed verification, citation evidence, and production reliability engineering

Questions or feedback? Get in touch.

Related Articles