arborist/aborist
russell@unturf.com 38d95dd21b
qa: warrant-lite — relation-question hard check (Ticket H)
Closes the lazy-anchor failure class fox surfaced in feedback-3
(2026-05-01) on "who is homer simpson's boss?":

  Claim: "Homer Simpson's boss is Mr. Burns."
  Cited span: voice-actor / Castellaneta bio prose
  Pre-warrant: pointer-linked, source-role allowed, coverage passes
  Post-warrant: WARRANT_MISSING violation, audit_mode capped at HYBRID

Pointer verification != warrant verification. A pointer resolves to
a span; a warrant requires the span to actually contain the claim's
named answer entity.

Adds aborist/qa/warrant.py:
  - is_relation_question(q) — regex shape detector for "who is X's Y?",
    "who is supermans girlfriend?", "who founded Z?", "boss of X" etc.
  - extract_answer_anchors(claim) — multi-word proper nouns ("Mr.
    Burns", "Lois Lane") with possessive 's stripping; solo-cap
    fallback that skips sentence-starter false positives
  - warrant_check(claim, spans) — at-least-one-anchor lexical match;
    vacuous-pass when claim has no proper-noun anchor

Wired into verify_claim_lattice via new params (question,
warrant_check_enabled). Per-claim WARRANT_MISSING violations cap
audit_mode at HYBRID using the same demote pattern as
lazy_anchor_demoted. CLI renders " · warrant missing" tail when
violations present so the failure mode is legible without scanning
the violations array.

Policy field claim_lattice_warrant_check_enabled added to
DEFAULT_POLICY / DEFAULT_QUERY_POLICY and the verifier-policy hash
field set so changes bump verifier_policy_hash.

Hard or soft? Per CLAUDE.md "Soft hash vs hard hash":
substring/lexical = hard. Output is binary (warrant present or not),
violations enter the proof path through violations[] alongside
SOURCE_ROLE_BLOCKED and CITATION_MISMATCH.

Deferred (follow-on commits):
  - full RELATION_PATTERNS table with relation-noun aliases
  - two-hop bridge detection ("X founded Y" + "Y is Z" -> "X is Z")
  - retrieval expansion for relation questions

Tests: 16 new unit tests in tests/test_warrant.py covering
is_relation_question, extract_answer_anchors, warrant_check
(happy path, lazy-anchor case, vacuous-pass, case-insensitive,
empty inputs). Full suite: 523 passed, 21 skipped.
2026-05-01 13:23:24 -04:00
..
distill storage cheats + TF-IDF retrieval fix 2026-04-27 17:24:51 -04:00
mesh mesh: per-peer audit chain-of-claims tracking on the wire 2026-04-28 19:41:25 -04:00
qa qa: warrant-lite — relation-question hard check (Ticket H) 2026-05-01 13:23:24 -04:00
search qa: strip 'all/there/know/everything' from retrieval queries; bench gains deflection rate 2026-04-30 20:15:25 -04:00
sources qa: self-reference thought chains — STRICT-as-fact substrate 2026-05-01 10:16:47 -04:00
__init__.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
cli.py qa: warrant-lite — relation-question hard check (Ticket H) 2026-05-01 13:23:24 -04:00
compress.py storage cheats + TF-IDF retrieval fix 2026-04-27 17:24:51 -04:00
document.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
evict.py storage cheats + TF-IDF retrieval fix 2026-04-27 17:24:51 -04:00
ingest.py storage cheats + TF-IDF retrieval fix 2026-04-27 17:24:51 -04:00
merkle.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
progress.py progress reporter + structured benchmark 2026-04-27 11:37:20 -04:00
snapshot.py add corpus-level snapshots: single-hash identity for the forest 2026-04-27 21:29:10 -04:00
source.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
store.py qa: G0 claim-lattice-pointer answer mode — CTI quote-by-pointer 2026-04-29 21:19:19 -04:00
wikitext.py verify: strip wikitext from context before substring matching 2026-04-28 15:48:07 -04:00