The verify_claim Consumer Contract
This page is the binding call/return contract of
scitex_clew.verify_claim() for downstream consumers
(scitex-live-paper, scitex-writer). It is audited against the source at
v0.7.0 (src/scitex_clew/_claim/_verify.py and
src/scitex_clew/_claim/_model.py).
Motivation: a consumer once integrated against an imagined API —
against= / bundle_root= keyword arguments, an assumed internal
git checkout, and a top-level result["status"] / verified_at —
and mismatched on all four axes. The actual contract follows.
Signature — one positional, no commit argument, no checkout
import scitex_clew as clew
result = clew.verify_claim(claim_id_or_location) # -> dict
claim_id_or_locationis aclaim_id, a"paper.tex:L42"location string, or a bare file path (resolves to the first claim on that file).There is no
against=,bundle_root=, or commit argument. The only other parameters are internal per-pass performance caches (hash_cache=None/chain_cache=None) threaded in byverify_all_claims.Clew never runs git. It re-hashes the claim’s
source_fileon disk, at its current state. To verify “as of commit X”, the host must check out X first, then callverify_claim. This git-agnosticism is by design; there is no verify-at-commit helper.Side effect: the claim row’s
statusandverified_atare written back to the database on every resolved verification.
Return shape
An unresolved lookup is the only case with a top-level status:
{"status": "not_found", "message": "No claim found for '...'"}
A resolved claim returns exactly four top-level keys:
Key |
Type |
Meaning |
|---|---|---|
|
dict |
|
|
bool |
stored |
|
bool |
upstream |
|
list |
human-readable notes (hash match/mismatch, chain run counts, errors) |
Gotchas:
statusandverified_atlive insideresult["claim"], never at the top level of a resolved result.result["claim"]["status"]is refreshed to this pass’s outcome;result["claim"]["verified_at"]is the value as read at resolution time (the DB row receives a new timestamp, the returned dict does not).resolved_status/color/display_group/display_colorare not in this return — they are claims.json (schema v1.3) enrichment fields written byscitex_clew.export_claims_json().
Two status vocabularies
(a) VerificationStatus enum
(src/scitex_clew/_chain/_types.py) — for runs, files, chains, and
DAGs: VERIFIED, MISMATCH, SUSPECT, MISSING, UNKNOWN.
(b) Claim status strings stored on the claims row:
registered, verified, suspect, mismatch, missing —
plus not_found as a lookup outcome (never stored).
Outcome of |
Claim |
|---|---|
source file gone |
|
stored hash differs from current hash |
|
hash matches, chain fails |
|
hash matches, chain verifies |
|
never verified (initial) |
|
v0.7.0 rename: the claim status partial was renamed to
suspect. Legacy stored "partial" rows are normalized to
"suspect" at read time. suspect now deliberately spans both
vocabularies — one word for “locally valid, upstream not confirmed”.
Keep separate: client-side transient UI states (verifying,
error) are not clew statuses, and paper-level badge
vocabularies (e.g. the unified feed’s badge_state:
all_verified / partial / failing) are a separate aggregate
vocabulary.
claims.json v1.3 enrichment and precedence
export_claims_json() adds per claim: resolved_status, color
(bare 6-hex, no #), chain_has_exception, chain_has_frozen,
display_group, display_color, exception_reasons.
resolved_status follows the precedence
mismatch/missing > [verified claims only: exception >
frozen] > suspect > verified > registered. Chain
overrides never promote an unverified claim — no false-green.
Canonical full-7 palette (_CLAIM_PALETTE, bare hex):
Status |
Hex |
Hue |
|---|---|---|
|
|
green |
|
|
amber |
|
|
red |
|
|
dark red |
|
|
grey |
|
|
violet |
|
|
blue (Okabe-Ito) |
4-bucket display collapse: verified+frozen → verified;
suspect+registered → suspect;
mismatch+missing → failed; exception →
exception. Consumers holding the pre-v1.3 table (partial
d29922, missing cf222e, light/dark variants) have a stale copy —
read palette / display_palette / display_groups from the
exported claims.json instead of hardcoding.
Database selection precedence
resolve_db_path() (src/scitex_clew/_db/_core.py) resolves the
store in three tiers:
Explicit
db_path—VerificationDB(db_path=...)and, new in 0.7.0,render_dag(..., db_path=...).The
SCITEX_CLEW_DB_PATHenvironment variable.Project-root walk from the current working directory (nearest ancestor containing
.gitorpyproject.toml) →<root>/.scitex/clew/runtime/db.sqlite.
Host-side re-verify recipe:
# HOST owns git: check out the pinned commit, point clew at the bundle DB.
subprocess.run(["git", "-C", bundle_root, "checkout", pinned_commit], check=True)
os.environ["SCITEX_CLEW_DB_PATH"] = f"{bundle_root}/.scitex/clew/runtime/db.sqlite"
result = clew.verify_claim(claim_id)
claim_status = result.get("claim", {}).get("status") # not result["status"]
See also the scitex-clew skill page
05_verify-claim-contract.md for the same contract in skill form.