Skip to main content
Deterministic verification guards for computational legal claims.
Block unproven legal claims before they become liabilities.
QWED-Legal is a verification layer for deterministic, computational legal claims. It is designed to sit between untrusted LLM or workflow output and any downstream legal action. QWED-Legal verifies only what can be deterministically proven, such as:
  • Date calculations (business days, holidays, leap years)
  • Liability arithmetic (cap percentages, tiered amounts, indemnity multipliers)
  • Structured contradictions between modeled clauses
  • Citation format for supported reporters
  • Provenance metadata (hash integrity, disclosure markers, allowed models)
Interpretive legal reasoning is not automatically trusted. When proof is not possible, the correct outcome is to reject the claim or mark it unverified.

Verification boundaries

QWED-Legal operates under strict limits:
  • Only deterministic claims can be verified.
  • Ambiguous or interpretive output is rejected or marked unverified.
  • Legal reasoning is not assumed correct without proof.
  • If something cannot be proven, it must not pass.
QWED-Legal is not:
  • a legal reasoning engine
  • a source of legal truth
  • a replacement for lawyers
  • a contract drafting or review platform
  • a guarantee that every legal output can be verified

Guard coverage

Not every guard provides full formal verification. Some operate on partial rules or structured validation and should not be treated as complete legal proof. A valid result from a PARTIAL / HEURISTIC or MIXED guard does not mean the underlying legal claim is correct. It means the claim matched a supported structural pattern, or that a deterministic sub-computation succeeded over parsed inputs.

Verification traces

As of v0.4.0, every guard returns a verification_trace — an ordered list of VerificationStep records that make each decision auditable. A trace is not a narrative explanation. Each step carries an evidence_type that classifies how its output was derived: Only DETERMINISTIC steps constitute proof. PARSED, INFERRED, HEURISTIC, and UNSUPPORTED steps are visible for auditability but must not be treated as verification.

Structured diagnostics

Every guard result exposes to_diagnostic(claim_inputs=...), which returns a LegalDiagnosticResult — the same 3-layer contract described in Verification Diagnostics. The status is one of: The LegalDiagnosticResult dataclass is frozen and enforces the authority contract in __post_init__:
  • VERIFIED requires a non-empty proof_ref matching sha256:[0-9a-f]{64}.
  • UNVERIFIABLE and BLOCKED reject proof_ref entirely.
  • agent_message must be a non-empty string.
Attempting to construct a result that violates these rules raises ValueError — “VERIFIED without proof” or “BLOCKED with proof” are not caller conventions, they are unrepresentable. LegalDiagnosticResult.verified() also refuses to mint a proof_ref unless the evidence trace contains at least one DETERMINISTIC step. Direct calls over traceless or non-deterministic evidence raise ValueError. Guard adapters demote those verdicts to UNVERIFIABLE instead. This covers traceless or transport-stripped "consistent" verdicts and consistent verdicts with empty claim_texts. Blank agent messages fall back to status-specific defaults instead of crashing. See No proof without a deterministic step.

Per-guard status mapping

Not every guard can ever return VERIFIED. Guards whose evidence is inherently non-authoritative (citation format, heuristic clause checks, fairness, self-declared provenance) map their passing outcomes to UNVERIFIABLE on purpose: Guards where VERIFIED is documented as “Never” are an honesty contract: their strongest positive result is still non-authoritative, so downstream gates that key on proof_ref will correctly refuse to admit.

Proof references

For VERIFIED results, proof_ref is a SHA-256 hash over the RFC 8785 (JCS) canonical JSON of the proof evidence — the claim inputs, the full verification_trace (with evidence_type on every step), and a snapshot of the guard result. See Verification Diagnostics — Proof references for the full API (compute_proof_ref, resolve_proof_ref) and the tamper-detection contract.

Quick example

Verify a deadline calculation

A valid format result does not prove that the cited authority exists or is controlling. result.verified is always False, and result.status is unverifiable_authority when the format matches. CitationGuard has no case-law database. It only confirms the citation matched a supported structural pattern.

Architecture

High-level flow

Guard selection flow

These are examples of supported checks catching unsupported claims. They are not proof that every legal hallucination is detectable.

Why not just trust the LLM?

LLMs are probabilistic and can fail in legally significant ways: QWED-Legal treats LLM output as untrusted input. It does not assume correctness. It requires proof for every property it verifies. When proof is not possible, it fails closed.

Jurisdiction support

DeadlineGuard supports jurisdiction-specific holidays:

Next steps