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.
pip install qwed-legal

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.
GuardStatusWhat it checks
DeadlineGuardDETERMINISTICDate arithmetic and business-day calculations for supported, structured inputs
LiabilityGuardDETERMINISTICCap and tiered amount computations for supported numeric inputs
ClauseGuardPARTIAL / HEURISTICLimited text-based clause consistency and contradiction checks (explicit Z3 path is deterministic)
CitationGuardPARTIAL / HEURISTICCitation shape / format validation, not authoritative existence proof
JurisdictionGuardPARTIAL / HEURISTICStructured checks around governing law and forum combinations
StatuteOfLimitationsGuardMIXEDDeterministic date arithmetic over a parsed limitation-period lookup; the lookup itself is PARSED, not authority proof
IRACGuardPARTIAL / HEURISTICIRAC structure and consistency checks, not proof of legal reasoning
FairnessGuardHEURISTIC / FAIL-CLOSEDCounterfactual consistency signal only; never returns verified=True — fairness cannot be proven by text substitution (requires an external LLM client)
ContradictionGuardMIXEDDeterministic Z3 SAT/UNSAT over a limited set of modeled clause categories; unmodeled inputs fail closed
ProvenanceGuardDETERMINISTICSHA-256 hash integrity, disclosure markers, model allowlist, timestamp validity
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:
evidence_typeMeaningis_proven()
DETERMINISTICProven by math/logic (Z3, date arithmetic, exact compare)True
PARSEDRead/matched from structure or a lookup table — not authority proofFalse
INFERREDPattern/keyword derived — may be wrong on edge casesFalse
HEURISTICApproximate/statistical signalFalse
UNSUPPORTEDGuard cannot model this input — fail-closedFalse
Only DETERMINISTIC steps constitute proof. PARSED, INFERRED, HEURISTIC, and UNSUPPORTED steps are visible for auditability but must not be treated as verification.
from qwed_legal import StatuteOfLimitationsGuard, trace_to_dict

result = StatuteOfLimitationsGuard().verify(
    claim_type="breach_of_contract",
    jurisdiction="California",
    incident_date="2020-01-01",
    filing_date="2023-01-01",
)

for step in result.verification_trace:
    print(step.step, step.evidence_type, "->", step.output)

# JSON-safe export for audit logs (each entry includes an explicit is_proven flag)
serialized = trace_to_dict(result.verification_trace)

Quick example

Verify a deadline calculation

from qwed_legal import DeadlineGuard

guard = DeadlineGuard()
result = guard.verify(
    signing_date="2026-01-15",
    term="30 business days",
    claimed_deadline="2026-02-14",
)

print(result.verified)            # False
print(result.computed_deadline)   # 2026-02-27
print(result.message)
from qwed_legal import CitationGuard

guard = CitationGuard()
result = guard.verify("Brown v. Board of Education, 347 U.S. 483 (1954)")

print(result.format_valid)  # True - matches a supported citation format
print(result.status)        # "unverifiable_authority" - format ok, authority unknown
print(result.verified)      # False - authority can never be proven by format
print(result.parsed_components)
# {'volume': 347, 'reporter': 'U.S.', 'page': '483'}
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.
InputClaimed resultExample outcome
”Net 30 business days from Dec 20”Wrong computed dateBlocked by DeadlineGuard
”Liability cap: 2x fees”Wrong cap arithmeticBlocked by LiabilityGuard
Structured liability conflict”Clauses are consistent”Blocked by ContradictionGuard
Unsupported citation reporter”Valid citation”Blocked by CitationGuard format checks

Why not just trust the LLM?

LLMs are probabilistic and can fail in legally significant ways:
Failure modeExampleRisk
Fabricated authorityAI cites a nonexistent or malformed legal sourceSanctions, bad filings
Deadline mistakes”30 business days” miscomputedMissed obligations, defaults
Clause inconsistencyTwo provisions cannot both be trueDisputes, unenforceable terms
False certaintyModel states a legal conclusion without proofLiability, audit failure
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:
from qwed_legal import DeadlineGuard

# US holidays (default)
us_guard = DeadlineGuard(country="US")

# UK holidays
uk_guard = DeadlineGuard(country="GB")

# California-specific holidays
ca_guard = DeadlineGuard(country="US", state="CA")

Next steps