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.
24 lines
580 B
Python
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",
|
|
]
|