Installation
Quick start
As of v5.0.0, the
status field may return INCONCLUSIVE, BLOCKED, or UNKNOWN in addition to VERIFIED and ERROR. Natural-language math queries return INCONCLUSIVE when the inner engine succeeds, because the LLM translation step is non-deterministic. See the trust boundary documentation for details.Async client
Methods
verify(query)
Auto-detect and verify any claim.verify_math(expression)
Verify mathematical expressions.verify_logic(query)
Verify logical constraints (QWED-Logic DSL).verify_code(code, language)
Check code for security vulnerabilities.verify_sql(query, schema_ddl, dialect)
Validate SQL queries against a schema.verify_fact(claim, context)
New in v4.0.0
verify_fact fails closed when the QWED service can’t complete the check. If the client can’t connect (httpx.ConnectError) or the request times out (httpx.TimeoutException), it returns status="UNVERIFIABLE" and is_verified=False. It doesn’t raise. The local PII pre-check still runs first, but it is not a fact check, so passing it never produces VERIFIED.
verify_stats(query, file_path)
New in v4.0.0
verify_consensus(query, mode, min_confidence)
New in v4.0.0
verify_image(image_path, claim)
New in v4.0.0
verify_batch(items)
Verify multiple items at once. The response is aBatchResult whose items are per-item records — for math items the verdict is a DiagnosticResult nested under each item’s result, so check result.status and result.proof_ref per item rather than relying on an aggregate.
math items, supply equality claims (e.g., "x + x = 2*x") to receive proof results. Bare expressions without an = return status: "UNVERIFIABLE" with the simplified form in developer_fields.simplified — they are never reported as verified. The legacy is_valid flag is preserved inside developer_fields.is_valid for backward compatibility.
Verification Context
New in v7.1.0
to_verification_context() method on the verifier classes.
Client methods
All three methods are available on bothQWEDClient and QWEDAsyncClient and call the corresponding Verification Context endpoints.
create_verification_context_from_diagnostic(diagnostic, query, verifier)
Create a schema-valid Verification Context document from aDiagnosticResult dict. Optional keyword arguments: verifier_version and attestation_token. A VERIFIED diagnostic without a valid attestation token fails closed to BLOCKED (fail-closed).
validate_verification_context(document)
Validate a document against the v1.0 JSON Schema.resolve_verification_context(document)
Resolve the document’sproof_ref evidence commitment.
Re-exported types and helpers
qwed_sdk re-exports the Verification Context v1.0 model, so you can build, validate, and resolve documents locally without an API round trip:
compute_document_proof_ref(document)derives the canonicalsha256:<64-hex>commitment for a document.resolve_document_proof_ref(document)returnsTrueonly when the document isVERIFIED, schema-valid, and the storedproof_refmatches the re-derived commitment. Everything else returnsFalse(fail-closed).
to_verification_context() on verifiers
Every verification engine that definesto_verification_context() maps its DiagnosticResult to a Verification Context document: the Code, Consensus, DSL Logic, Fact, Graph Fact, Image, Logic, Reasoning, Schema, SQL, Stats, and Symbolic verifier classes, plus the BatchFactVerifier and MultiVLMVerifier helpers. Math and the secure code executor do not define the method — pass their DiagnosticResult to create_verification_context_from_diagnostic() instead:
VERIFIED documents carry a sha256 proof_ref, while UNVERIFIABLE and BLOCKED documents carry proof_ref: null with admission DENY.
Verification cache
qwed_sdk.cache.VerificationCache is the persistent SQLite-backed cache for verification results. It reduces LLM cost on repeated queries.
Cache entries are context-bound. A hit requires an exact match of both the normalized query and the trust-bound CacheContext.
A mismatch on any context dimension is a deterministic miss. The cache never falls back to a query-only match. This prevents cross-provider, cross-model, cross-policy, and cross-tenant replay of VERIFIED results.
CacheContext
Every get() and set() call requires a CacheContext. All fields participate in the cache key.
Usage
Miss conditions
cache.get(query, context) returns None when any of the following holds:
- No entry exists for this
(query, context)pair. - The stored entry has expired (TTL, default 24 hours).
- The stored context fingerprint does not match
context(replay guard). - The entry uses the legacy v1 schema. The cache never returns legacy rows.
Constructor options
cache_dir— Directory for the SQLite database. Defaults to~/.qwed/cache.ttl— Time-to-live in seconds. Defaults to 24 hours.
CLI
qwed context command group.
Verification cache
qwed_sdk.cache provides a context-bound SQLite cache for verification results.
A cache hit requires an exact match of both the normalized query and the trust-bound CacheContext. Any mismatch on a context dimension yields a deterministic miss — the cache never crosses trust boundaries. The cache also ignores legacy entries that lack a context fingerprint.
CacheContext
Trust-bound context dimensions required for every cache operation. All fields participate in the cache key; omitting or changing any field causes a deterministic cache miss.
str
required
Provider or API endpoint identifier (for example,
"openai", "claude").str
required
Model or deployment name (for example,
"gpt-4o").str
required
Verifier policy version string (for example,
"v1").Optional[str]
default:"None"
Tenant or session scope identifier. Use to prevent cross-tenant replay.
Optional[str]
default:"None"
Environment or config fingerprint for additional binding.
VerificationCache(cache_dir=None, ttl=86400)
Optional[str]
default:"~/.qwed/cache"
Directory for the SQLite cache database.
int
default:"86400"
Time-to-live in seconds (default: 24 hours).
get() treats entries older than ttl as a miss and deletes them on access.MAX_ENTRIES = 1000. When set() grows the table past the cap, set() evicts the least-recently-accessed entries.
get(query, context)
Return the cached result for (query, context), or None on miss.
get() returns None when:
- No entry exists for the
(query, context)pair. - The entry has expired (older than
ttl). - The stored context fingerprint does not match
context(defence-in-depth replay guard).
str
required
The verification query string. Normalized (lowercased, whitespace-collapsed) before hashing.
CacheContext
required
Trust-bound context that must match exactly. Omitting this argument raises
TypeError.Optional[Dict[str, Any]]
The cached result dict, or
None on any miss.set(query, result, context)
Store a verification result bound to (query, context).
The composite primary key (key, context_fingerprint) keeps identical queries under different contexts as independent entries.
str
required
The verification query string.
Dict[str, Any]
required
Verification result to cache.
set() serializes this dict as JSON.CacheContext
required
Trust-bound context to bind this entry to.
clear()
Remove all cached entries and reset stats.
get_stats()
Return a CacheStats dataclass with hits, misses, total_entries, cache_size_bytes, and a hit_rate property.
print_stats()
Print a formatted summary of cache statistics to stdout. Uses ANSI colors when colorama is installed.
Breaking change (Issue #187).
get() and set() now require a CacheContext argument. Calls like cache.get("2+2") or cache.set("2+2", result) raise TypeError. The on-disk schema is cache_v2 with composite PRIMARY KEY (key, context_fingerprint). The cache never returns entries from the legacy v1 cache table.