arborist/aborist/qa/__init__.py
russell@unturf.com 57cf1b183b
add Q&A layer: v9.8 providence_cache writes with Merkle-bound proofs
aborist/qa/ implements the cache-first answer flow from the providence
whitepaper, scaled up to v9.8's full 8-dim admissibility invariant.

cache_key = SHA-256 of:
  source_root | question_hash | model_profile_hash | conversation_hash
  | governance_policy_hash | schema_version | canonicalization_version
  | chunking_version

Any drift in any dimension yields a distinct cache_key — prior records
cannot serve. Falsification states (failed/stale/quarantined) gate
every cache hit.

- qa/keys.py        — pure hash functions, deterministic & testable
- qa/client.py      — ChatClient Protocol + StubClient + OpenAI-compatible
                      HTTP client (vllm/llama.cpp/uncloseai compatible)
- qa/runner.py      — ask(): lookup -> hit (no LLM call, hit_count++)
                      OR miss (call client, write record, audit event,
                      proof binds answer to source root)
- cli.py            — `aborist ask` and `aborist providence` subcommands
- pyproject.toml    — httpx promoted from extras to core (used by both
                      html and qa); selectolax stays in [html] extras

Smoke (StubClient, no network): cache miss writes record with chunk_0
Merkle proof reconstructing source_root; cache hit returns same record
without calling client; 1085 audit events chained 0 breaks across
ingest/derive/evict/rehydrate/providence_write.
2026-04-27 08:01:23 -04:00

24 lines
580 B
Python

"""Q&A layer: answer a question about a document, write a provable record."""
from aborist.qa.client import ChatClient, OpenAICompatibleClient, StubClient
from aborist.qa.keys import (
cache_key,
conversation_hash,
governance_policy_hash,
model_profile_hash,
question_hash,
)
from aborist.qa.runner import DEFAULT_POLICY, ask
__all__ = [
"ChatClient",
"OpenAICompatibleClient",
"StubClient",
"cache_key",
"conversation_hash",
"governance_policy_hash",
"model_profile_hash",
"question_hash",
"DEFAULT_POLICY",
"ask",
]