arborist/tests
russell@unturf.com bb8450d402
qa: JSON mode uses pointer IDs (E1, E2, …) — close hallucination loop
JSON mode previously presented content-addressed evidence_ids
(``Eed1b6e396``-style) in the EVIDENCE block headers and expected
the same in the model's claim output. Hermes-3-8B was fabricating
plausible near-miss IDs (e.g. ``E1b6e396`` when the runtime had
``Eed1b6e396``) on cross-document relationship questions →
UNKNOWN_EVIDENCE_ID → UNGROUNDED, even when the answer text was
factually correct (e.g. "Homer Simpson's boss is Mr. Burns.").

Switching the prompt-facing surface to short pointer IDs (``E1``,
``E2``, …) — same as claim_lattice_pointer mode — closes the
hallucination loop:

  - Pointer IDs are short, enumerable, and fabrication-obvious.
    The model can't invent ``E27`` if only ``E1``-``E10`` were shown;
    out-of-range IDs read as schema violations at first glance.
  - The runtime still resolves each pointer_id to its content-
    addressed evidence_id internally and stores THAT in
    ``evidence_id_pairs`` for the cache & run-DAG. Cache_keys stay
    run-stable; only the prompt-facing string changes.
  - JSON schema unchanged (``evidence_ids: [str, ...]``), so vLLM
    guided_json continues to constrain output shape.

Live-test verification: ``who is homer simpson's boss?`` went from
JSON-mode UNGROUNDED 0/1 (hallucinated ``E1b6e396``) to STRICT 1/1
(model emits ``E1``, resolves cleanly). Homer fixture pin removed —
runs against the JSON default now.

Files touched:
  - aborist/qa/evidence.py: render_evidence_block_for_json uses
    e.pointer_id instead of e.evidence_id.
  - aborist/qa/verify.py: verify_claim_lattice_json switched from
    evidence_map_by_evidence_id to evidence_map_by_pointer_id;
    captures both pointer_ids (model-emitted) and evidence_ids
    (run-stable) in claim_statuses + evidence_id_pairs.
  - aborist/qa/{runner,query}.py: claim_lattice_json_system_prompt
    + grounding_reminder describe pointer IDs; example shifts from
    ``E........`` placeholder to ``E1``.
  - tests/test_verify_json.py: stub _ev() takes pointer_id; four
    fixtures updated to set it.
  - tests/test_qa_quality_live.py: Homer fixture unpinned (now
    runs default JSON mode and grounds). Red-fish-blue-fish
    fixture pinned to pointer mode — JSON mode hits a separate
    token-budget runaway on "plot of X" prose-summary shapes
    (~2/3 of samples blow max_tokens with whitespace spam after
    the closing brace). Different failure mode, addressed in a
    later commit.

460 unit tests + 11 live fixtures pass.
2026-04-30 15:27:55 -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' — mass-burn fresh providence rows 2026-04-29 16:56:59 -04:00
test_burn_doc.py cli: extend 'aborist burn' to documents and cores 2026-04-28 17:32:40 -04:00
test_claim_lattice.py qa: bare-name guard, lazy-anchor demote, game tie-in noisy markers 2026-04-30 12:36:59 -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_dag.py qa: chain-segment failure localization + re-prompt repair tier 2026-04-29 19:27:33 -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 qa: per-claim status taxonomy on verifier + repair-action plans on sidecar 2026-04-29 18:37:52 -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_qa_quality_live.py qa: JSON mode uses pointer IDs (E1, E2, …) — close hallucination loop 2026-04-30 15:27:55 -04:00
test_query.py qa: per-run Merkle-DAG provenance — run_dag_root on every providence record 2026-04-29 18:44:17 -04:00
test_reclassify.py verify: layered strategies + entity policies, rename VISUAL → UNGROUNDED 2026-04-28 16:58:31 -04:00
test_repair.py qa: chain-segment failure localization + re-prompt repair tier 2026-04-29 19:27:33 -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: per-claim status taxonomy on verifier + repair-action plans on sidecar 2026-04-29 18:37:52 -04:00
test_verify_json.py qa: JSON mode uses pointer IDs (E1, E2, …) — close hallucination loop 2026-04-30 15:27:55 -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