- Wikitext base prose section now reflects reality: to_base() runs in two places (before LLM call in query.py/runner.py AND inside verify_quotes) gated by policy["base_version"]. Both sides see prose; Hermes can quote source paragraphs verbatim instead of escaping [[wikilinks]], and Wikipedia chunks ship with ~43% fewer tokens. - Build/test block now points at the real targets: verify-shards, analyze-shards, chain-check-shards. The bare 'make analyze' target doesn't exist — only the cross-shard variants do. - New "Hygiene after any state-changing op" callout: chain-check-shards for one-second per-shard break count, analyze-shards for full audit. - Audit-chain invariant block points at the same targets. - Orientation protocol updated: --shards-dir replaces --db (the latter refers to a single-DB setup that's no longer the canonical path), and chain-check-shards is added to the per-session ritual.
12 KiB
Agent Blackops — aborist
This repo is operated by agent blackops for fox/timehexon on the unsandbox / unturf / permacomputer platform.
Identity shard: ~/git/unsandbox.com/blackops/BLACKOPS.md.
What aborist is
A content-addressed, Merkle-committed document store. Implements the runtime spec from Merkle Providence Reverse RAG (April 2026 whitepaper) scaled up to the Merkle-AGI v9.8 admissibility ledger. Tends "trees and forests of cross-linked information" — the namesake.
Three layers stacked on one SQLite file:
- Surface — ingested documents (Wikipedia dumps, HTML pages, anything with a URI). Chunked, Merkle-rooted, FTS5-indexed.
- Core — distilled documents (haiku/keyword/equation-scale) Merkle-bound back to source surface(s) via per-chunk inclusion proofs in
derivations.proof_blob. Recursive: cores derive from cores. The "planet toward center" compression. - Providence cache — Q&A records keyed on the v9.8 8-dim invariant. Each record carries an
audit_modeset by the post-LLM faithfulness verifier (aborist/qa/verify.py): STRICT (every quoted claim verbatim-grounded), HYBRID (mixed source/emergent), UNGROUNDED (no verbatim grounding — purely emergent from training).
Source papers (read first if confused)
~/git/unfirehose-nextjs-logger/whitepaper/merkle-providence-reverse-rag-whitepaper.rst— canonical whitepaper source (rst, builds the PDF). Edit here, not the PDF.~/Downloads/merkle-providence-reverse-rag-whitepaper.pdf— built artifact; mirrors the rst above~/Downloads/merkle-agi-dag_v7.txt— formal substrate (TLV encoding A1, public quantization A2, collision-resistant hash A3, theorems T1–T5)~/git/proxy.unturf.com/pkg/verified/merkle.go— fox's existing Go merkle implementation. Aborist Python ports its conventions exactly.~/git/proxy.unturf.com/docs/merkle-tree.md— convention reference
Architecture
aborist/
├── merkle.py # Python port of proxy.unturf.com Go conventions
├── store.py # v9.8 SQLite schema, audit chain helpers
├── document.py # Document, Edge, Chunker (TokenChunker default)
├── source.py # Source ABC: iter_documents() -> Iterator[Document]
├── ingest.py # batched: normalize -> chunk -> merkle -> upsert
├── evict.py # hot->cold + rehydrate (v9.8 falsification on drift)
├── search/ # SearchBackend ABC + AuditMode + FTS5
├── sources/ # one file per corpus
│ ├── wikipedia.py # WikipediaSqlDump (cur + old tables)
│ └── html_page.py # HtmlPageSource (selectolax, robots-aware)
├── distill/ # surface->core distillation
│ ├── base.py # Distiller ABC + DistillationResult
│ ├── first_sentence.py # FirstSentenceDistiller (no-ML stub)
│ ├── tfidf.py # TfidfKeywordDistiller (pure-Python TF-IDF)
│ └── runner.py # batched: derive + per-contrib-chunk proofs
├── qa/ # Q&A: 8-dim cache_key + Merkle-bound answers
│ ├── client.py # ChatClient + StubClient + OpenAICompat
│ ├── keys.py # cache_key, question_hash, ... (pure functions)
│ ├── verify.py # layered verifier: quote → span → entity
│ └── runner.py # ask(): cache -> infer -> verify -> classify -> write
├── wikitext.py # to_base(): wikitext → plain prose (BASE_VERSION-pinned)
└── cli.py # ingest / search / verify / stats / distill /
# evict / rehydrate / ask / providence / emergent /
# reclassify / analyze
Build, test, run
Every workflow is a make target. Bare python commands are not the user interface.
make bootstrap # venv + editable install with [dev] extras
make test # pytest -q (49 tests)
make all # bootstrap + fetch-cur + ingest-cur + verify + stats
make fetch # cur (82 MB) + old.1 (640 MiB) + old.2 (252 MiB) + concat
make ingest-cur # ingest snapshot articles
make ingest-old # ingest revision history (~hours)
make verify-shards # round-trip Merkle proofs on a random sample (cross-shard)
make analyze-shards # cross-shard compression spectrum + audit integrity
make chain-check-shards # audit-chain break count per shard (0 = intact)
Hygiene after any state-changing op (table rebuild, reclassify run, governance hash bump, mass falsify): make chain-check-shards for a one-second sanity (every shard should report 0), then make analyze-shards for the full spectrum + chain audit. Chain breaks are the loudest possible signal that something corrupted the audit log — catch them at the seam, not in production.
aborist/cli.py adds: analyze, distill --kind {surface,core}, evict, rehydrate, ask, providence, emergent (list UNGROUNDED/HYBRID records or --aggregate to rank unverified quotes — corpus-growth signal), reclassify (re-run the verifier against existing live providence records under the current entity policy; no LLM calls; --compare runs all four policies side-by-side, --dry-run reports without writing). --batch-size defaults to 200 docs/transaction; lower it only to bound memory peaks.
Schema invariants (do not break)
- Aborist is a v9.8 store. Every Document carries
chunking_version,canonicalization_version,schema_version. 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 onstate='live'. Drift detection (rehydrate vs source root mismatch) flips tostale.- Audit chain. Every state-changing op writes one row in
audit_eventswithevent_hash = sha256(prev_event_hash || canonical(body)). Chain integrity is verified inmake analyze-shards(full audit) ormake chain-check-shards(one-second per-shard break count,0= intact). Never insert intoaudit_eventsdirectly — useaborist.store.append_audit. - Cores never evict.
evict_to_coldonly toucheskind='surface'. - Idempotent re-ingest. Same content → same
document_root→ no-op insert. Same URI + different content → new doc +supersedesedge linking new → old (lossless history).
Conventions (do not silently change)
- Merkle: non-commutative
HashCombinewith prefix0x03. Leaves0x00. Odd-element rule = self-duplicate, NOT zero-pad.MerkleProof.siblingscarries explicitis_leftflag — never sort lexically. - Chunker default =
tok-512-v1. Changing the default bumpschunking_versionand stales every prior cache record. Add a new chunker as a newnameinstead. - Canonicalization =
norm-v1(NFC, collapsed whitespace). Same rule. - Schema =
v9.8.0. Same rule. audit_modeis decided by the verifier, never asserted unconditionally. Three layered strategies inaborist/qa/verify.py, tried in order; first to find evidence classifies the answer:- quote — model wrapped claims in double quotes per system prompt. Sequential pairing: 1st & 2nd
", 3rd & 4th, etc. (NOT regex pairing — that captures inter-pair prose as a phantom span when the model writes"title" prose "quote"). - span — bullet/sentence lines from the answer appear verbatim in context. Catches models that quote inline without
"..."marks. - entity — multi-word proper-noun phrases appear verbatim in context. Gated by
entity_policy ∈ {strict, hybrid, drop, proximity}. Defaultproximity: STRICT only when N=3 verified entities cluster within W=300 chars in source (cast list / infobox / roster). Otherwise HYBRID/UNGROUNDED. Distinguishes structural grounding from incidental mention. Lives inDEFAULT_QUERY_POLICY["entity_policy"]so any change bumpsgovernance_policy_hash. Trichotomy across all paths: STRICT = every evidence unit (≥1) verifies. HYBRID = some verify, some don't. UNGROUNDED = no evidence or none verifies. Persisted onprovidence_cache.audit_mode+verifier_method; cache-hits return the stored mode. Never overclaim — STRICT is a verifiable claim, not a default.
- quote — model wrapped claims in double quotes per system prompt. Sequential pairing: 1st & 2nd
- Verifier stays binary; falsifications carry soft signal. No per-quote diagnosis fields on hard verifier output.
verify_quotesreturns evidence units + classification; the falsify+reclassify loop owns "why didn't this ground" for the operator. Don't bolt confidence scores or partial-match indicators ontoverify.py. - Wikitext base prose.
aborist/wikitext.py:to_base(raw)converts MediaWiki wikitext → plain prose deterministically (mwparserfromhell-backed; pinned byBASE_VERSION = "wikitext-base-v1"). Applied before the LLM call inaborist/qa/runner.pyandaborist/qa/query.py(gated onpolicy["base_version"]), and again insideverify_quotesso the verifier compares like-against-like. Both sides — model and verifier — see prose; the model can quote source paragraphs verbatim instead of escaping[[wikilinks]], and Wikipedia chunks ship to Hermes with ~43% fewer tokens.policy["base_version"]lives inDEFAULT_POLICY/DEFAULT_QUERY_POLICYso it folds intogovernance_policy_hash; bumpingBASE_VERSIONinvalidates every prior cache record's 8-dim cache_key on next lookup. Optional dep — installs withoutmwparserfromhellkeep_wikitext_to_base = Noneandpolicy["base_version"] = None, leaving raw wikitext in both context and verifier (graceful fallback, no failure mode). - Soft hash vs hard hash. Hard = SHA-256 (commitments, proofs, cache_key). Soft = embeddings/TF-IDF/similarity (training, ranking, distillation candidate selection). Never mix — soft never enters proof path.
Live endpoints
- LLM:
https://hermes.ai.unturf.com/v1(Hermes-3 Llama-3.1-8B-FP8-Dynamic on vLLM, 82K ctx, no auth).uncloseai.comis marketing only — has no/v1. Override via--endpointorABORIST_LLM_ENDPOINT. - Wikipedia dumps:
https://dumps.wikimedia.org/archive/2003/2003-05-16/en/.robots.txtreturned 404 → no rules.
Hot path / gotchas
- Parser is hand-rolled in
aborist/sources/wikipedia.py(char-position state machine, escape-aware). After the v9.8 commit it's 4× faster viastr.find+ slicing — easy to break by reverting to char-by-char loops. cProfile any change. PRAGMA synchronous=NORMALis set per-connection instore.connect(). Safe under WAL (the journal_mode is set inSCHEMA_SQL). Don't downgrade to FULL without a measured reason — costs ~5x throughput.- HTML source has optional deps:
pip install '.[html]'forselectolax. The CLI surfaces--source htmlonly if the import succeeds. - Background ingest/distill processes: stdout is buffered. Use
export PYTHONUNBUFFERED=1orpython -u. Per blackops top-level rule. - Disk pressure. Full cur ingest ~2 GB; full old ingest ~5–8 GB.
df -h /home/foxfirst.
Operational rules
- I propose, fox decides. Unsure = ask. Can't ask = stop.
- No autonomous destructive ops. No
clean-data,clean-db, force-push, or DB drops without explicit instruction. - Never add
Co-Authored-Byor "Generated with Claude" lines to commits. Professional commit messages only — code speaks for itself. - Always
export PYTHONUNBUFFERED=1for long-running processes. Buffered output disappears when processes die. - Fail-closed. Cleanup crew, not demolition.
- DRY in context — single source of truth, no sprawl.
- Never say "AI" — always say "machine learning."
- Prefer "defect" over "bug."
- Check robots.txt before any web fetch the user didn't authorize.
Orientation protocol
date -u
pwd
git log --oneline -5
git status
make test
make chain-check-shards # per-shard audit-chain integrity (0 = intact)
.venv/bin/aborist --shards-dir ~/.aborist/shards stats
.venv/bin/aborist --shards-dir ~/.aborist/shards analyze --gravity-top 5
Then ask fox what the mission is.