qa: warrant-lite — wire JSON variant of claim_lattice verifier
Initial Ticket H commit (38d95dd) only plumbed warrant into
verify_claim_lattice (pointer mode). The JSON variant
verify_claim_lattice_json was missed — and the CLI's
--answer-mode claim_lattice (the JSON path) was producing
EVIDENCE-LINKED on relation-question records without warrant
firing.
This adds the same warrant block to verify_claim_lattice_json:
question + warrant_check_enabled params, identical
WARRANT_MISSING violations, identical demote-to-HYBRID
semantics, same warrant_missing_claim_idxs field on the verdict.
Plumbs question= and warrant_check_enabled= through call sites
in runner.py and query.py for the JSON path.
Live verified: warrant correctly checks the FULL cited span
(not the spotlight excerpt). On the Homer-Simpson "boss is Mr.
Burns" case, the chunk text DOES contain "Mr. Burns" elsewhere
in the paragraph — warrant rightly passes. The misleading
spotlight excerpt that fox flagged is a separate render-layer
issue (failure to spotlight the load-bearing slice), not a
warrant failure.
Note: cache-hit path does not currently restore violations into
the result dict (providence_cache schema has no violations
column; run_dag_blob stores only hashes). On cache hits the
warrant_tail in CLI render won't surface even when warrant
fired at write-time. Follow-up needs a schema migration to
persist violations alongside the cached record.
This commit is contained in:
parent
38d95dd21b
commit
182bb67996
3 changed files with 43 additions and 0 deletions
|
|
@ -1835,6 +1835,10 @@ def query(
|
|||
max_claims_per_answer=int(policy.get(
|
||||
"claim_lattice_max_claims_per_answer", 12
|
||||
)),
|
||||
question=question,
|
||||
warrant_check_enabled=bool(policy.get(
|
||||
"claim_lattice_warrant_check_enabled", True
|
||||
)),
|
||||
)
|
||||
rendered = verdict["rendered_text"]
|
||||
answer_text = rendered if rendered else raw_answer
|
||||
|
|
|
|||
|
|
@ -652,6 +652,10 @@ def ask(
|
|||
max_claims_per_answer=int(policy.get(
|
||||
"claim_lattice_max_claims_per_answer", 12
|
||||
)),
|
||||
question=question,
|
||||
warrant_check_enabled=bool(policy.get(
|
||||
"claim_lattice_warrant_check_enabled", True
|
||||
)),
|
||||
)
|
||||
rendered = verdict["rendered_text"]
|
||||
answer_text = rendered if rendered else raw_answer
|
||||
|
|
|
|||
|
|
@ -1467,6 +1467,8 @@ def verify_claim_lattice_json(
|
|||
max_evidence_per_claim: int = DEFAULT_MAX_POINTERS_PER_CLAIM,
|
||||
min_citation_coverage: float = DEFAULT_MIN_CITATION_COVERAGE,
|
||||
max_claims_per_answer: int = DEFAULT_MAX_CLAIMS_PER_ANSWER,
|
||||
question: str | None = None,
|
||||
warrant_check_enabled: bool = True,
|
||||
) -> dict:
|
||||
"""Deterministic verifier for ``answer_mode="claim_lattice"`` (JSON).
|
||||
|
||||
|
|
@ -1710,6 +1712,38 @@ def verify_claim_lattice_json(
|
|||
else:
|
||||
audit_mode = "UNGROUNDED"
|
||||
|
||||
# Warrant-lite — same relation-question hard check as the pointer
|
||||
# variant. See verify_claim_lattice for the rationale (Ticket H,
|
||||
# 2026-05-01). Identical demote-to-HYBRID semantics; the JSON
|
||||
# variant carries the same WARRANT_MISSING violations & the same
|
||||
# warrant_missing_claim_idxs field on the verdict.
|
||||
warrant_missing_claims: list[int] = []
|
||||
if warrant_check_enabled and question and is_relation_question(question):
|
||||
for cs in claim_statuses:
|
||||
if cs.get("status") not in ("EVIDENCE_LINKED", "EVIDENCE_LINKED_PARTIAL"):
|
||||
continue
|
||||
cited_eids = cs.get("evidence_ids") or []
|
||||
cited_spans = [
|
||||
obj.span
|
||||
for eid in cited_eids
|
||||
for obj in [evidence_map_by_evidence_id_local(evidence_map, eid)]
|
||||
if obj is not None
|
||||
]
|
||||
ok, missing = warrant_check(cs.get("text") or "", cited_spans)
|
||||
if not ok:
|
||||
warrant_missing_claims.append(cs.get("claim_idx"))
|
||||
violations.append({
|
||||
"kind": "WARRANT_MISSING",
|
||||
"claim_idx": cs.get("claim_idx"),
|
||||
"missing_anchors": missing,
|
||||
"rationale": (
|
||||
"claim names answer entity not present in any "
|
||||
"cited span — pointer-linked but warrant missing"
|
||||
),
|
||||
})
|
||||
if warrant_missing_claims and audit_mode == "STRICT":
|
||||
audit_mode = "HYBRID"
|
||||
|
||||
# Same `verifier_method` as the pointer variant ("claim_lattice")
|
||||
# so the providence_cache CHECK constraint accepts both. The mode
|
||||
# is disambiguated downstream via `answer_mode` on the run-DAG &
|
||||
|
|
@ -1725,4 +1759,5 @@ def verify_claim_lattice_json(
|
|||
"rendered_text": rendered_text,
|
||||
"evidence_id_pairs": evidence_id_pairs,
|
||||
"json_fixups": json_fixups,
|
||||
"warrant_missing_claim_idxs": warrant_missing_claims,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue