# `aborist.store` The v9.8 SQLite schema, the audit chain, and the cross-shard read-only view. Every table that holds runtime state lives here. ## Schema overview (per shard) ``` documents – one row per source document, keyed on document_root chunks – per-document chunk content + tier (hot/cold) chunks_fts – FTS5 contentless index, rowid = chunks.chunk_id merkle_nodes – internal-node hashes for proof reconstruction edges – src_root → dst_root link graph (wikilink, href, …) derivations – core_root ← src_root with proof_blob (Merkle) providence_cache – Q&A records keyed on the v9.8 8-dim cache_key audit_events – linear chain; event_hash = sha256(prev || canonical(body)) falsifications – record_id → state transition + reason + actor snapshots – named corpus roots (one hash names a forest) document_http_meta – ETag + Last-Modified for crawler conditional fetches concept_relations – per-shard synonym/rivalry/category/antonym overlay mesh_* – federation tables (off by default) ``` ## v9.8 invariants (do not break) - **Aborist is a v9.8 store.** Every providence record carries the full **8-dim cache_key**: `source_root | question_hash | model_profile_hash | conversation_hash | governance_policy_hash | schema_version | canonicalization_version | chunking_version`. Bumping any one invalidates prior records on lookup. - **`falsification_state ∈ {live, failed, stale, quarantined}`.** Cache lookups must filter on `state='live'`. Drift detection flips to `stale`. - **Audit chain.** Every state-changing op writes one row in `audit_events` with `event_hash = sha256(prev_event_hash || canonical(body))`. Chain integrity is verified in `make analyze-shards`. **Never insert into `audit_events` directly — use `aborist.store.append_audit`.** - **Cores never evict.** `evict_to_cold` only touches `kind='surface'`. - **Idempotent re-ingest.** Same content → same `document_root` → no-op insert. Same URI + different content → new doc + `supersedes` edge linking new → old (lossless history). ## API surface ```python from aborist.store import ( connect, # writable connection to a single shard connect_query, # read-only UNION view across all shards discover_shards, # list *.db files in a shards_dir transaction, # BEGIN IMMEDIATE / COMMIT / ROLLBACK context manager get_meta, set_meta, append_audit, # the ONLY way to write audit_events ) ``` Cross-shard reads use `connect_query(shards_dir=...)` which ATTACHes every `*.db` and creates UNION views over the shardable tables (`documents`, `chunks`, `merkle_nodes`, `edges`, `derivations`, `providence_cache`, `audit_events`, `falsifications`, `concept_relations`). ## Performance pragmas `connect()` applies these per-connection: - `journal_mode=WAL` (set in SCHEMA_SQL once at first ingest) - `synchronous=NORMAL` (skip per-commit fsync; safe under WAL) - `cache_size=-65536` (64 MB page cache) - `temp_store=MEMORY` (no /tmp churn for temp tables) Don't downgrade to `synchronous=FULL` without a measured reason — costs ~5× throughput. ## Diagrams ![module graph](../diagrams/aborist-modules.svg) ![ingest pipeline](../diagrams/ingest-pipeline.svg) ## Source [`aborist/store.py`](../../aborist/store.py)