arborist/tests
russell@unturf.com b39e79b0c1
qa: claim_lattice JSON mode — both modalities first-class in the substrate
Brings the JSON variant back as a third ANSWER_MODE, distinct from the
pointer variant. The substrate exposes both: pointer for prose-
distribution / small-model paths (Hermes-3 8B), JSON for grammar-
constrained / large-reasoning-model paths (vLLM guided_json,
Claude/GPT-4 native JSON, Qwen 3.6 reasoner). Agents pick by setting
`policy["answer_mode"]`; both fold into governance_policy_hash so
records under different modes never alias.

Components:

- aborist/qa/verify.py:
    * ANSWER_MODES = ("quote", "claim_lattice_pointer", "claim_lattice")
    * `_lenient_json_parse(raw)` — defensive pre-parser. Strips markdown
      fences, trims preamble/suffix to {/}, normalizes curly quotes,
      fixes trailing commas. Returns (parsed, fixups[]) so the verifier
      logs which drift had to be peeled. Lenient on syntax, strict on
      semantics: parsed JSON still has to schema-check.
    * CLAIM_LATTICE_JSON_SCHEMA — JSON Schema for the {"claims":[...]}
      shape. Used by vLLM guided_json sampling-time constraint.
    * `verify_claim_lattice_json(answer_json_text, evidence_map, ...)` —
      runs the same hard checks as verify_claim_lattice (evidence_id
      resolves, source_role allowed, no manual quotes, claim text non-
      empty, claim textually overlaps evidence) but on content-
      addressed evidence_ids directly. Returns the same verdict shape
      plus a `json_fixups` list.

- aborist/qa/client.py: ChatClient Protocol & OpenAICompatibleClient
  gain optional `extra_body` kwarg. Forwarded as additional fields in
  the JSON request payload — opaque pass-through for vLLM-specific
  knobs like `guided_json`. Endpoints that don't recognize a key
  silently drop it. StubClient ignores; tests inspect via self.calls.

- aborist/qa/evidence.py: `render_evidence_block_for_json` and
  `render_evidence_map_for_json` — JSON-mode prompts label blocks with
  the content-addressed evidence_id (long hex) since that's what the
  model cites in its JSON. Pointer mode keeps using the short
  pointer_id.

- aborist/qa/query.py:
    * Imports the JSON verifier + schema + JSON-mode evidence renderer.
    * Message-build branch: `elif answer_mode == "claim_lattice"`
      builds the same per-chunk evidence map as pointer mode, but
      uses `claim_lattice_json_system_prompt` and labels blocks with
      evidence_id.
    * LLM call: when answer_mode=claim_lattice and policy
      `claim_lattice_use_guided_json` is on, passes
      `extra_body={"guided_json": SCHEMA}` so vLLM constrains output.
    * Verifier dispatch: new `elif answer_mode == "claim_lattice"`
      branch calls verify_claim_lattice_json.
    * DAG persistence: lattice-mode raw_answer / parsed_lattice /
      rendered_text threading now applies to both pointer and JSON.
    * DEFAULT_QUERY_POLICY adds `claim_lattice_json_system_prompt`,
      `claim_lattice_json_grounding_reminder`, and
      `claim_lattice_use_guided_json` (default True).

- tests/test_verify_json.py: 14 tests covering the lenient parser
  (strict pass-through, fence strip, preamble trim, curly-quote
  normalize, trailing-comma fix, multi-fixup, hard-fail) and the
  JSON verifier (STRICT on resolved claims, HYBRID on partial,
  UNGROUNDED on schema invalid, fence recovery, manual-quote
  violation, source-role block).

The whitepaper rewrite to 13.9.1 (substrate exposes both modalities,
both first-class) becomes accurate post-ship — JSON mode now exists
in code as it always existed in the architecture's intent.

554 tests pass.
2026-04-30 11:30:08 -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: title-purity rerank + 6th hard check (CITATION_MISMATCH) 2026-04-29 21:57:37 -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_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: claim_lattice JSON mode — both modalities first-class in the substrate 2026-04-30 11:30:08 -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