The phrase-pattern retrieval route (commit 1b8677d) closed the
RETRIEVAL side of reference-frame failure; this ticket closes
the ANSWER side.
New module aborist/qa/frame.py:
FrameDetection dataclass (frame_kind, reference_title,
reference_uri, confidence). Sidecar — never enters cache_key
or governance_policy_hash.
detect_frame(question, sources, phrase_match_roots) — heuristic
detector. Reference-frame classification fires when:
(a) phrase route surfaced at least one source, AND
(b) at least one phrase-matched source is a reference work,
determined by:
- title parenthetical disambig (`(novel)` / `(film)` /
`(play)` / `(franchise)` / etc.), OR
- body sample contains ≥3 DISTINCT fiction markers
(novel / published / protagonist / plot / ...).
Distinct-marker count keeps the heuristic robust against a
history article saying "novel approach" twice.
aborist/qa/query.py:
Calls detect_frame for lattice modes only. Body sample uses the
ARTICLE LEAD (chunk_idx=0, post-wikitext-strip) — fiction
markers cluster in the lead on Wikipedia, not in plot chunks
that may have been query-relevance-ranked higher.
New policy field claim_lattice_polarity_preamble injected as a
user-role message before the grounding_reminder when
frame_kind == "reference". Format-string with
{reference_title} placeholder.
Result dict carries frame_detection (kind / title / uri /
confidence) for renderer + bench consumption.
aborist/cli.py:
Renderer adds a `reference frame: <title>` line when
frame_detection.kind == "reference". Skipped for literal /
no-phrase-route / ambiguous rows.
Live verification — Orwell case:
PRE : "The text does not directly state that Oceania has always
been at war with East Asia."
POST : "In George Orwell's dystopian novel Nineteen Eighty-Four,
the nation of Oceania is always at war with Eastasia,
but this is a result of propaganda and doublethink, not
actual historical continuity. The war with Eastasia is
a fabricated conflict to maintain control..."
Multi-frame compilation: distinguishes propaganda claim from
fictional-actual continuity, exactly the polarity contract from
the ticket §2 abstraction.
Literal queries (capital of france) unchanged — polarity preamble
only injects when frame_kind classifies as "reference".
22 new tests (19 in test_frame.py + 3 in test_cli_render.py).
Full suite: 734 passed (was 712, +22).
Directive D3 status: ½ → ✓. Ticket #000002 closed.
All seven structural directives now ✓:
D1, D2, D5 (were ✓);
D3 #000002, D4 #000001, D6 #000003, D7 #000005 (closed in this
series).
280 lines
10 KiB
Python
280 lines
10 KiB
Python
"""Frame-detection tests (#000002 / Module L scope).
|
|
|
|
Pins the heuristic detector that classifies a claim-lattice query as
|
|
``literal`` / ``reference`` / ``ambiguous`` / ``no_phrase_route`` based
|
|
on the phrase-pattern retrieval signal + per-source reference-work
|
|
indicators.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from aborist.qa.frame import (
|
|
FrameDetection,
|
|
_body_indicates_reference_work,
|
|
_source_is_reference_work,
|
|
_title_indicates_reference_work,
|
|
detect_frame,
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Title-suffix detection
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_title_suffix_recognises_novel_film_play():
|
|
assert _title_indicates_reference_work("Jurassic Park (film)")
|
|
assert _title_indicates_reference_work("Jurassic Park (novel)")
|
|
assert _title_indicates_reference_work("Hamlet (play)")
|
|
assert _title_indicates_reference_work("The Lord of the Rings (franchise)")
|
|
assert _title_indicates_reference_work("Star Wars (video game)")
|
|
|
|
|
|
def test_title_suffix_handles_multiword_disambig():
|
|
assert _title_indicates_reference_work("Some Comic (graphic novel)")
|
|
assert _title_indicates_reference_work("Some Show (TV series)")
|
|
assert _title_indicates_reference_work("Some Plot (short story)")
|
|
|
|
|
|
def test_title_suffix_doesnt_fire_on_literal_geography():
|
|
assert not _title_indicates_reference_work("Oceania")
|
|
assert not _title_indicates_reference_work("Asia")
|
|
assert not _title_indicates_reference_work("New York City")
|
|
assert not _title_indicates_reference_work("Springfield, Missouri")
|
|
|
|
|
|
def test_title_suffix_doesnt_fire_on_disambig_for_real_things():
|
|
"""Geographic / biographical disambig suffixes should NOT trip
|
|
the reference-work detector."""
|
|
assert not _title_indicates_reference_work("Cleveland (Ohio)")
|
|
assert not _title_indicates_reference_work("Mercury (planet)")
|
|
assert not _title_indicates_reference_work("Mercury (element)")
|
|
assert not _title_indicates_reference_work(
|
|
"John Smith (politician)"
|
|
)
|
|
|
|
|
|
def test_title_suffix_handles_none_or_empty():
|
|
assert not _title_indicates_reference_work(None)
|
|
assert not _title_indicates_reference_work("")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Body fiction-marker density
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_body_density_recognises_orwell_lead():
|
|
"""The Nineteen_Eighty-Four article opens with high fiction-
|
|
marker density: 'novel by George Orwell' + 'fiction' + 'plot' /
|
|
'characters' / 'published' typically all in the first KB."""
|
|
sample = (
|
|
"Nineteen Eighty-Four is a dystopian social science fiction "
|
|
"novel by English novelist George Orwell. The narrative "
|
|
"follows the protagonist Winston Smith, a low-ranking "
|
|
"member of the ruling Party. The novel was published in "
|
|
"1949. The plot explores themes of totalitarianism. "
|
|
"Characters include Big Brother and Julia."
|
|
)
|
|
assert _body_indicates_reference_work(sample)
|
|
|
|
|
|
def test_body_density_doesnt_fire_on_geography():
|
|
sample = (
|
|
"Oceania is a continent located in the Pacific Ocean. It "
|
|
"comprises Australia, New Zealand, and various smaller "
|
|
"Pacific island nations. The continent has a diverse "
|
|
"geography with mountains, deserts, and coral reefs. The "
|
|
"population is concentrated along the coastlines."
|
|
)
|
|
assert not _body_indicates_reference_work(sample)
|
|
|
|
|
|
def test_body_density_doesnt_fire_on_one_incidental_novel_use():
|
|
"""A history article saying 'this was a novel approach' shouldn't
|
|
trip the detector — single use vs marker density."""
|
|
sample = (
|
|
"The reform of 1850 introduced a novel approach to "
|
|
"regional administration. Local governors retained "
|
|
"significant autonomy under the new framework. The "
|
|
"policy persisted for several decades before being "
|
|
"replaced. " * 2
|
|
)
|
|
assert not _body_indicates_reference_work(sample)
|
|
|
|
|
|
def test_body_density_handles_none_or_empty():
|
|
assert not _body_indicates_reference_work(None)
|
|
assert not _body_indicates_reference_work("")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _source_is_reference_work — composition
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_source_is_reference_work_via_title():
|
|
src = {
|
|
"title": "Hamlet (play)",
|
|
"body_sample": "Hamlet is a tragedy.",
|
|
}
|
|
assert _source_is_reference_work(src)
|
|
|
|
|
|
def test_source_is_reference_work_via_body_only():
|
|
src = {
|
|
"title": "Nineteen Eighty-Four",
|
|
"body_sample": (
|
|
"Nineteen Eighty-Four is a dystopian science fiction "
|
|
"novel by George Orwell, published in 1949. The plot "
|
|
"follows Winston Smith. The novel explores themes of "
|
|
"totalitarianism. Characters include Big Brother."
|
|
),
|
|
}
|
|
assert _source_is_reference_work(src)
|
|
|
|
|
|
def test_source_is_not_reference_work_for_geography():
|
|
src = {
|
|
"title": "Oceania",
|
|
"body_sample": (
|
|
"Oceania is a geographic region comprising Australia, "
|
|
"New Zealand, and Pacific Islands."
|
|
),
|
|
}
|
|
assert not _source_is_reference_work(src)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# detect_frame — end-to-end classification
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_detect_frame_no_phrase_route():
|
|
"""No phrase route fired → no_phrase_route classification."""
|
|
sources = [{"document_root": "abc", "title": "Oceania"}]
|
|
fd = detect_frame("oceania population", sources, phrase_match_roots=set())
|
|
assert fd.frame_kind == "no_phrase_route"
|
|
assert fd.reference_title is None
|
|
|
|
|
|
def test_detect_frame_no_phrase_route_when_arg_is_none():
|
|
sources = [{"document_root": "abc", "title": "Oceania"}]
|
|
fd = detect_frame("oceania population", sources, phrase_match_roots=None)
|
|
assert fd.frame_kind == "no_phrase_route"
|
|
|
|
|
|
def test_detect_frame_reference_via_title_suffix():
|
|
"""Phrase route fired AND matched source has a (film) suffix →
|
|
reference-frame classification."""
|
|
sources = [
|
|
{
|
|
"document_root": "aaa",
|
|
"title": "Jurassic Park (film)",
|
|
"document_uri": "https://en.wikipedia.org/wiki/Jurassic_Park_(film)",
|
|
"body_sample": "Jurassic Park is a 1993 American science fiction action film.",
|
|
},
|
|
]
|
|
fd = detect_frame(
|
|
"what dinosaurs were in jurassic park?",
|
|
sources,
|
|
phrase_match_roots={"aaa"},
|
|
)
|
|
assert fd.frame_kind == "reference"
|
|
assert fd.reference_title == "Jurassic Park (film)"
|
|
assert fd.confidence > 0.5
|
|
|
|
|
|
def test_detect_frame_reference_via_body_density_orwell():
|
|
"""Phrase route fired AND matched source has fiction body markers
|
|
→ reference-frame even without a title suffix (Nineteen
|
|
Eighty-Four canonical case)."""
|
|
sources = [
|
|
{
|
|
"document_root": "bbb",
|
|
"title": "Nineteen Eighty-Four",
|
|
"document_uri": "https://en.wikipedia.org/wiki/Nineteen_Eighty-Four",
|
|
"body_sample": (
|
|
"Nineteen Eighty-Four is a dystopian science fiction "
|
|
"novel by George Orwell, published in 1949. The plot "
|
|
"follows Winston Smith, a Party member. Characters "
|
|
"include Big Brother and Julia. The novel explores "
|
|
"totalitarianism."
|
|
),
|
|
},
|
|
]
|
|
fd = detect_frame(
|
|
"has oceania always been at war with east asia",
|
|
sources,
|
|
phrase_match_roots={"bbb"},
|
|
)
|
|
assert fd.frame_kind == "reference"
|
|
assert fd.reference_title == "Nineteen Eighty-Four"
|
|
|
|
|
|
def test_detect_frame_ambiguous_when_phrase_matched_but_not_reference():
|
|
"""Phrase route fired but the matched source is a non-fiction
|
|
article (e.g. a verbatim quotation that happens to appear in a
|
|
history page). Classification: ambiguous."""
|
|
sources = [
|
|
{
|
|
"document_root": "ccc",
|
|
"title": "List of common phrases",
|
|
"document_uri": "https://example.org/list",
|
|
"body_sample": (
|
|
"This is a list page. It contains various phrases "
|
|
"and their meanings. Geographic regions include "
|
|
"Asia, Africa, and Europe."
|
|
),
|
|
},
|
|
]
|
|
fd = detect_frame(
|
|
"always been at war with east asia",
|
|
sources,
|
|
phrase_match_roots={"ccc"},
|
|
)
|
|
assert fd.frame_kind == "ambiguous"
|
|
assert fd.reference_title is None
|
|
|
|
|
|
def test_detect_frame_picks_first_reference_source_when_multiple():
|
|
"""When phrase route surfaced multiple sources and ≥2 are
|
|
reference works, pick the first by retrieval order."""
|
|
sources = [
|
|
{
|
|
"document_root": "aaa",
|
|
"title": "Jurassic Park (film)",
|
|
"body_sample": "An action film.",
|
|
},
|
|
{
|
|
"document_root": "bbb",
|
|
"title": "Jurassic Park (novel)",
|
|
"body_sample": "A novel by Michael Crichton.",
|
|
},
|
|
]
|
|
fd = detect_frame(
|
|
"dinosaurs in jurassic park",
|
|
sources,
|
|
phrase_match_roots={"aaa", "bbb"},
|
|
)
|
|
assert fd.frame_kind == "reference"
|
|
# First-by-order is the film.
|
|
assert fd.reference_title == "Jurassic Park (film)"
|
|
|
|
|
|
def test_detect_frame_skips_non_phrase_matched_sources():
|
|
"""A reference-work source that wasn't phrase-matched doesn't
|
|
trigger the reference frame (otherwise any retrieval that
|
|
happens to include a (film)-suffixed source would over-fire)."""
|
|
sources = [
|
|
{
|
|
"document_root": "aaa",
|
|
"title": "Hamlet (play)", # reference work but not phrase-matched
|
|
"body_sample": "A tragedy.",
|
|
},
|
|
]
|
|
fd = detect_frame(
|
|
"hamlet plot summary",
|
|
sources,
|
|
phrase_match_roots=set(), # no phrase route
|
|
)
|
|
assert fd.frame_kind == "no_phrase_route"
|