arborist/tests
russell@unturf.com d6f98929d7
qa: breadth-required filter for multi-token queries + light token stem
Fox 2026-04-29: 'who is supermans girlfriend?' returned 7-of-8 unrelated
`Girlfriends`-titled articles (TV show, movies, songs); only 1 actual
Superman-related doc made it. Two coupled defects:

1. Title-overlap accept fired on ANY single-token match. A 2-token
   query was admitting docs that shared only ONE qtoken. `Girlfriends`
   passed because its title matched "girlfriend" even though no
   "superman" anywhere in the doc.

2. `_body_density_passes` required at least HALF the qtokens — too
   lenient for the 2-token case (1 of 2 = 50% = pass).

3. Possessive plural mismatch: question_hash strips apostrophes so
   "superman's" → "supermans", but the corpus has bare "Superman".
   `body.count("supermans")` returns 0 even on the canonical doc.

Three coordinated fixes in `aborist/qa/query.py`:

- New `_stem_token_for_match(t)` helper: strips a trailing `s` for
  tokens > 4 chars (so `supermans` → `superman`, `girlfriends` →
  `girlfriend`). Conservative: skips short tokens & double-s endings
  to avoid `class` / `boss` / `pass` corruption.

- `_body_density_passes` now uses `_body_count_with_stem` (literal-
  first, stem-fallback) AND a tightened breadth threshold:
    ≤ 2 tokens   require ALL of them
    3+ tokens    require N - 1 (allow one weak signal token to miss)

- `_filter_by_title_relevance` mirrors the same breadth threshold for
  title-overlap. Synonym fallback (any-match against synonym_expand)
  is preserved ONLY for 1-token queries — otherwise a stray synonym
  hit (e.g. AMD synonym matching an Intel-only title) over-recalls.

End-to-end on the actual corpus (3.4M articles, 8 shards):

  before: 'supermans girlfriend' → 7 unrelated `Girlfriends` titles, 1 Superman doc
  after:  Lois_Lane in top-K (the canonical answer), other Superman-related
          docs alongside, Girlfriends-only-titled docs filtered out

Tests:
- test_query_filter_requires_breadth_for_multi_token_queries — synthetic
  3-doc corpus pinning the new behavior (Lois Lane keeps; girlfriends-tv
  & superman-music both drop).
- test_query_filter_one_token_query_still_synonym_expands — pin the
  1-token loose path is preserved (no over-tightening).

349 passed, 1 skipped.

Burned the two stale UNGROUNDED girlfriend-query cache records so a
fresh `make query` exercises the new filter end-to-end.
2026-04-29 16:47:00 -04:00
..
crawler crawler: skip feeds + sitemaps at ingest (they're discovery, not knowledge) 2026-04-29 05:55:28 -04:00
fixtures verify: strip wikitext from context before substring matching 2026-04-28 15:48:07 -04:00
__init__.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
test_burn.py cli: 'aborist burn' — kindergarten leaf delete with audit event 2026-04-28 17:03:30 -04:00
test_burn_doc.py cli: extend 'aborist burn' to documents and cores 2026-04-28 17:32:40 -04:00
test_cli_render.py cli: human render for query by default; --json for raw; ensure_ascii=False 2026-04-29 10:14:36 -04:00
test_compress.py storage cheats + TF-IDF retrieval fix 2026-04-27 17:24:51 -04:00
test_concepts.py concept overlay: synonym expansion + rivalry exclusion 2026-04-27 12:34:00 -04:00
test_distill.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
test_distill_recursive.py recursive distillation: core -> depth+1 core 2026-04-27 07:54:30 -04:00
test_evict.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
test_grok_source.py add Grok export source: conversations + media posts 2026-04-27 13:49:42 -04:00
test_html_source.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
test_ingest.py verify: layered strategies + entity policies, rename VISUAL → UNGROUNDED 2026-04-28 16:58:31 -04:00
test_inspect.py inspect: interior_elision diagnosis — model dropped a (...) aside from source 2026-04-29 16:10:51 -04:00
test_keys.py qa: question_hash strips articles + verifier coverage drops stopwords 2026-04-29 14:00:44 -04:00
test_llm_context_base.py qa: pipe wikitext-base-v1 into LLM context (was verifier-only) 2026-04-28 17:08:49 -04:00
test_merkle.py phase 0 explore: aborist core + sources + distill + evict 2026-04-27 07:53:18 -04:00
test_mesh.py mesh: cryptographic foundation, off by default 2026-04-27 19:00:24 -04:00
test_mesh_aead.py mesh: optional AEAD body encryption under per-epoch shared secret 2026-04-28 17:34:39 -04:00
test_mesh_chain.py mesh: per-peer audit chain-of-claims tracking on the wire 2026-04-28 19:41:25 -04:00
test_mesh_cli.py mesh: sync default-holds records younger than 1 hour (kindergarten window) 2026-04-29 16:07:24 -04:00
test_mesh_cli_pull.py mesh: 'pull' CLI verb — fetch document body from a peer 2026-04-28 17:33:27 -04:00
test_mesh_wire.py mesh: HTTP gossip wire — signed envelopes + 5 message types 2026-04-28 16:57:04 -04:00
test_mesh_wire_e2e.py mesh: HTTP gossip wire — signed envelopes + 5 message types 2026-04-28 16:57:04 -04:00
test_migration_audit_mode.py verify: layered strategies + entity policies, rename VISUAL → UNGROUNDED 2026-04-28 16:58:31 -04:00
test_qa.py qa: post-LLM faithfulness verifier sets STRICT/HYBRID/VISUAL audit_mode 2026-04-28 15:45:08 -04:00
test_query.py qa: breadth-required filter for multi-token queries + light token stem 2026-04-29 16:47:00 -04:00
test_reclassify.py verify: layered strategies + entity policies, rename VISUAL → UNGROUNDED 2026-04-28 16:58:31 -04:00
test_resume.py resumable ingest + per-shard audit chain integrity 2026-04-27 11:29:27 -04:00
test_snapshot.py add corpus-level snapshots: single-hash identity for the forest 2026-04-27 21:29:10 -04:00
test_tfidf.py add TF-IDF keyword distiller 2026-04-27 07:55:53 -04:00
test_vcs_source.py add git and mercurial repo sources for self-play 2026-04-27 18:17:39 -04:00
test_verify.py qa: question_hash strips articles + verifier coverage drops stopwords 2026-04-29 14:00:44 -04:00
test_versioned_ingest.py storage cheats + TF-IDF retrieval fix 2026-04-27 17:24:51 -04:00
test_wikipedia_old.py prepare full Wikipedia 2003-05-16 ingest: cur + old (revisions) 2026-04-27 08:10:42 -04:00
test_wikipedia_xml.py add Phase IV Wikipedia XML + abstract sources 2026-04-27 17:24:28 -04:00
test_wikitext.py verify: layered strategies + entity policies, rename VISUAL → UNGROUNDED 2026-04-28 16:58:31 -04:00