Fox-supplied review expanding §2-§4 with axiomatic framing, CTI /
Merkle-AGI / PROMETHEUS-Σ interpretations, a concrete implementation
diff, and a strengthened test list. Captured verbatim as Appendix A.
Key refinements over the §2-§4 sketch:
- Splits retrieval-stage hash into retrieval_plan_hash +
retrieval_result_hash + retrieval_stage_hash (plan vs result
separation, axiomatically cleaner than embedding plan in the
retrieval-stage payload directly).
- Adds two new audit events: retrieval_plan_built and
retrieval_result_selected. Surfaces the retrieval inputs in the
audit chain (not just the run_dag), so cache-hits also commit
the plan via cache_hit_with_retrieval_plan.
- Distinguishes three keyword-handling cases for cache identity
(Case A/B/C) and lays out a clean boundary rule: keywords stay
in retrieval_plan unless they reach the model (then prompt_hash)
or affect routing policy (then retrieval_policy_hash).
- Promotes 'the map must be committed, not only the territory
reached' as a core principle. Operator-supplied maps (keywords,
routing modes, ranking policies) become first-class clauses
upstream of retrieval_result.
- Lists 12 concrete tests including the critical 'same sources,
different keywords → different run_dag_root' assertion that
proves the gap is closed.
Header note: Appendix A is authoritative when it disagrees with
§2-§4 above. The original §2-§4 sketch stays in place for
chronological context but is superseded by the appendix.
Six items from fox's de-novo synthesis (2026-05-01) landing as one
atomic commit. Each item references its motivation and respects the
v9.8 honesty boundary (no claims of semantic truth, no proof-path
contamination by soft signals).
NEW DOCS
--------
docs/cti-architecture.md
Maps today's modules onto the architectural layer cake fox named
in his synthesis: PROMETHEUS-Σ (controller) / CTI (claim-lattice
reasoning IR) / Merkle-AGI-DAG (commitment) / Reverse-RAG
(evidence direction) / v9.8 Providence (admissibility ledger) /
Hermes (weak proposer). Per-layer responsibility table + module
map showing which existing files implement which layer. The
architecture is real; the labels above name what's already there.
docs/naming-deferral.md
Argues why we keep internal terms (claim_lattice,
claim_lattice_pointer, verify_claim_lattice) instead of renaming
to architectural labels (CTI, PROMETHEUS-Σ). The rename costs
cache invalidation, ~150 test fixture references, schema CHECK
migration, blame-history disconnect, mesh peer coordination.
The bridge is the cti-architecture mapping doc — read it once,
then read code in code's vocabulary and prose in prose's
vocabulary. Lists four triggers that would invert the decision.
docs/self-reference-distillation-design.md
Successor to docs/self-reference-thought-chains-design.md (the
flat-source MVP). Maps STRICT claims onto the existing Distiller
/ Core / derivations infrastructure: each STRICT record becomes
a Fact-Core via a new ProvidenceDistiller, with per-cited-chunk
Merkle inclusion proofs back to Wikipedia source_roots. The
fact-graph grows; new claims attach by inheriting the proof
chain. CompositionDistiller (combining facts into new claims)
is explicitly deferred — that's reasoning machinery, not
infrastructure.
docs/test-coverage-audit-2026-05-01.md
Maps fox's §11 test list (16 items) against the codebase. 16/16
covered. Documents item #9's manual-quote-rule lifecycle: the
rule was retired from pointer mode in commit 224bfd6 after the
bench journey identified it was rejecting factually correct
claims; retained in JSON variant where the punctuation-rationale
argument doesn't apply. The audit doc itself is the requirements-
drift defense.
CODE
----
aborist/qa/keys.py:verifier_policy_hash
New pure function. Hashes the verifier-relevant subset of policy
(answer_mode + claim_lattice_* verifier knobs + entity_policy
fields + base_version). Folded into cache_key as an optional
9th dimension via a new keyword arg with backward-compat default
None — legacy 8-dim callers continue to work and produce the
pre-2026-05-01 hash result.
aborist/qa/{runner,query}.py
Compute verifier_policy_hash from the policy_variant and pass
to cache_key as the 9th dim. Records written from this commit
forward bind to the verifier-policy identity. Pre-existing 8-dim
records become cache-misses on next lookup — same migration cost
as any governance_policy_hash bump. The 9-dim form makes the
question "did the verifier rules change?" answerable from
cache_key diff alone, separate from "did the prompt change?"
CLAUDE.md
Adds "old maps vs runtime maps" engineering discipline to the
bench-maxing section. Codifies the principle: every base model
carries old maps from training time; the runtime carries the
fresh map; when they disagree, the runtime wins. Move authority
OUT of the model's prior and INTO runtime artifacts (pointer IDs
the runtime mints, source spans the runtime interpolates by
offset, evidence maps assembled per query, policy hashes that
fold prompt/verifier/retrieval into cache_key, hard checks run
by the verifier). Hermes' content-addressed-evidence-id
hallucination (commit bb8450d) is the canonical case study.
TESTS
-----
tests/test_keys.py
Six new tests for verifier_policy_hash:
- only hashes verifier subset (non-verifier fields don't change it)
- changes when verifier-relevant field changes
- empty-policy → stable
- 9-dim cache_key distinct from 8-dim
- 9-dim distinct under different verifier hashes
- 8-dim form preserved for legacy callers (None == omit)
DEFERRED (per fox + naming-deferral.md)
---------------------------------------
- PROMETHEUS-Σ as an extracted controller module — the dispatch
logic in runner.py + query.py already IS PROMETHEUS-Σ; an
explicit prometheus.py is a refactor with no behavior change.
Defer until a §5-rename-trigger fires.
507 tests pass (was 501 before, +6 from verifier_policy_hash
coverage).
Tickets are flat docs/ticket-NNNNNN-<slug>.md — actionable proposals
awaiting go/no-go, scoped defects, or queued enhancements.
Architecture references and bench journals stay un-numbered.
docs/TICKETS.md: index + convention + Next ID line so future shifts
know where the next number comes from. Renumbering protocol: every
new ticket commit bumps the Next ID line atomically with the new
ticket file. Status field tracks open / in progress / closed; closed
tickets keep the file in place as a design log.
docs/ticket-000001-retrieval-keywords-audit-gap.md: the ticket
opened in 73058b0, renamed and re-headered to fit the convention.
Per fox's '--retrieval-keywords' commit (2d6a86b), the keyword string
is nowhere in the audit chain — it influences cache_key only
indirectly via context_root + conversation_hash. Two runs with the
same question and different keywords that surface identical sources
are Merkle-indistinguishable; an audit replay can recover the chosen
documents but not the inputs that pulled them.
Doc-only ticket: design proposal for capturing keywords in the
run_dag retrieval stage and on the providence_cache row (Option A +
B), preserving the 8-dim cache_key invariant. Out of scope: folding
keywords into question_hash (Option C) — keywords are operator
metadata, not user intent.
Includes failure cases, three design options with trade-offs,
implementation sketch, scope boundaries, and a recommended cost/value
forecast (~1-2 hours, low risk, additive schema). Awaiting fox's
go/no-go before landing.
Closes the recursive-grounding gap fox surfaced today: aborist
tends Wikipedia trees but never grafts its own past Q&A records
into the forest. Each query starts from cold corpus retrieval;
prior providence_cache records sit unread until the same question
is re-asked (cache_key match). The "kindergarten thought chains"
framing names the gap — the system has a kindergarten of thoughts
(early STRICT records) that should mature into citable substrate
as they cool.
This commit lands the MVP — STRICT live providence records past
the kindergarten window become substrate via a new Source
subclass. Trust model per fox: "we trust strict statements as
fact unless a verifier falsifies it."
NEW
---
- docs/self-reference-thought-chains-design.md — full architecture
doc covering the four iteration-time gates, the recursive Merkle
proof story (Q2 → Q1 → Wikipedia chunk per v9.8's recursive-
cores insight), the falsification trust model (state=live as the
fail-closed gate), risks (lazy-anchor compounding, echo chambers,
storage bloat), and bench-impact estimate.
- aborist/sources/providence.py — ProvidenceSource(Source) with
four hard gates:
1. audit_mode == 'STRICT' (HYBRID/UNGROUNDED stay opaque)
2. falsification_state == 'live' (failed/stale/quarantined
excluded — verifier-falsification mechanism per fox)
3. now - created_at >= kindergarten_seconds (default 1h —
fresh thoughts cool first; kills tight echo loops)
4. anti-recursion: records whose answer text contains a
self-reference URI are skipped — first-generation only
- tests/test_providence_source.py — 10 unit tests covering each
gate plus the URI-scheme source-role classifier
- Makefile target `ingest-self-providence` (KG_SECONDS=3600
default; iterates each shard and self-promotes its STRICT live
records — cross-shard sharing happens via the existing
shards-dir UNION at retrieval time)
WIRE-UP
-------
- aborist/qa/query.py
- SOURCE_ROLE_BUDGET_WEIGHTS: self_reference_source = 1.0
(same as background — Wikipedia stays canonical primary;
self-reference is supplementary anchoring)
- SOURCE_ROLE_RANK_WEIGHTS: self_reference_source = 0.9
- _classify_source_role: short-circuits on aborist://providence/
URI prefix → self_reference_source regardless of title shape
- DEFAULT_QUERY_POLICY['claim_lattice_allowed_source_roles']
+= 'self_reference_source'
- aborist/qa/runner.py — same allowlist update for the
per-document `ask` path
- aborist/cli.py — `aborist ingest --source providence` reads the
providence_cache from the same shard it writes into;
--kindergarten-seconds flag plumbed through
NOT IN THIS COMMIT
------------------
- Aggregation of multiple Q&A records into synthesized summary
records (follow-on)
- Self-reference for HYBRID records (only STRICT is substrate
today; HYBRID could land later as a soft-anchor role with
lower trust)
- Live virtual sourcing (the design discusses it; MVP uses
snapshot ingestion so existing FTS / chunker / Merkle apply
with zero schema change)
- A live bench validating actual lift on self-reference questions
(requires running ingest-self-providence then bench; deferred
to follow-on commit on real data)
10 new unit tests pass; full suite at 482 passed / 21 skipped
(live fixtures gated).
New docs/verifier-semantic-gap-design.md captures the deep
roadmap item from docs/qa-modes-bench-2026-04-30.md ("Verifier
semantic check (soft signal) — did the claim's predicate match
the cited span's frame?").
Problem: the claim-lattice verifier's lexical coverage check
(≥30% claim-token overlap with cited span) passes any (claim,
span) pair that shares enough surface tokens, even when the
span never asserts the claim's predicate. Three concrete cases
captured from live bench data:
- Great Wall elevation: STRICT 1/1 cited to a chunk that
discusses "Outer China beyond the Great Wall" but contains
no elevation information at all.
- JP-dinos Triceratops/Operation-Genesis: model cites the
2003 video-game article for a claim about the 1993 film.
- Boltzmann constant value: model cites a chunk that names
the constant and its unit but never states the numerical
value.
Three candidate designs evaluated against §1.1 cases + the
hard architectural constraints (proof-path purity, determinism,
no external endpoints beyond Hermes, latency budget):
3a NLI cross-encoder sidecar (recommended)
3b TF-IDF predicate matching (cheap but high false-negative)
3c Per-claim re-prompt to Hermes (latency + self-eval bias)
Recommendation: 3a with cross-encoder/nli-MiniLM2-L6-H768
(~80M params, ~100MB weights, CPU-runnable, deterministic at
fp32). Default off, opt-in via `claim_lattice_semantic_check`
policy field. Demote-only sidecar — moves STRICT → HYBRID
when claim entailment fails, never invents grounding. Soft
signal stays out of the proof path, mirrors the existing
`lazy_anchor_demoted` pattern.
Estimated impact: ~5-8 STRICT demotes per 66-run bench
(false-positives removed from the ledger), +0.4s typical
latency. Six open questions for fox at end of doc.
Doc-only commit. No code changes. Implementation deferred.
Adds two architectural-fix sections to the QA-modes bench doc:
1. Pointer-IDs in JSON mode (commit bb8450d) — closes the
content-addressed evidence_id hallucination loop where
Hermes-3-8B emitted near-miss IDs (E1b6e396 vs the runtime's
Eed1b6e396) on cross-document relationships, landing
UNGROUNDED on factually correct answers. Switching to short
pointer IDs (E1, E2, …) made fabrication obvious and the
Homer Simpson fixture went UNGROUNDED 0/1 → STRICT 1/1.
2. JSON-mode stop-sequence (commit f23d3a3) — guards against
post-brace token runaway where Hermes spammed whitespace
until max_tokens exhausted on broad-descriptive shapes
(apollo program 3/3 runaway in the post-pointer-ID bench).
stop=["\n\n"] cuts the runaway since well-formed JSON-mode
output never contains a blank line.
Also adds a bench progression table showing the journey from
the morning baseline (JSON 19 errors, 26 STRICT) to the post-
pointer-ID evening run (0 errors, 31 STRICT, 56 grounded).
Each row was a named-failure → fix → re-bench cycle.
Post-retry / post-trim-and-verify bench showed the picture flipped:
JSON mode now leads on strict-rate (50%) and ties grounded count
(54) with zero errors, all at parity-or-better latency. Switching
the `make query` ANSWER_MODE default from `claim_lattice_pointer`
to `claim_lattice` so the human-facing CLI uses the strongest mode.
Library-level DEFAULT_ANSWER_MODE stays "quote" so unit tests using
StubClient aren't disrupted.
Doc updated with post-retry bench table + revised conclusion.
Live test harness:
- new test_homer_simpson_boss_is_mr_burns fixture (pinned to
pointer mode — JSON mode hallucinates evidence_ids on
cross-document relationships, pointer mode's short numeric
tags can't be fabricated). Documents the mode trade-off.
- test_laura_croft marker net broadened to absorb Hermes
single-sample variance (added "magazine", "video game",
"character", "fictional", "british" markers) plus a hard
"croft" anchor check. Both real entities still gate cleanly.
11/11 live fixtures pass at the new JSON default + pointer pin
on Homer. 460 unit tests + 11 live = 471 green; 10 skipped is
just the live tests in the default-skip path.
Three-way QA-quality bench (quote / pointer / JSON) over an expanded
22-question set × 3 samples = 198 LLM calls. Findings landed in
docs/qa-modes-bench-2026-04-30.md with per-question breakdown and
roadmap. Aggregate at bench time:
quote 31S 20H 15U 0e strict-rate 47% 7.7s
claim_lattice_pointer 14S 34H 18U 0e strict-rate 21% 4.4s
claim_lattice (JSON) 26S 12H 9U 19e strict-rate 39%* 4.4s
The 19 JSON-mode "errors" turned out to be HTTP 502 from vLLM upstream,
not parse failures — clustered, all on the JSON-mode pass, plausibly
correlated with `guided_json` stressing the grammar engine.
Two improvements based on findings:
(1) OpenAICompatibleClient grew retry on transient 502/503/504 with
exponential backoff (0.5/1/2s, 3 attempts default). Network-layer
errors (ConnectError, ReadTimeout, RemoteProtocolError) get the
same retry. Smooths over the cluster without changing semantics:
persistent failures still raise, transient bursts no longer
dominate the error column. Helps all modes; JSON benefits most.
(2) Pointer-cap behavior changed from hard SCHEMA_INVALID to
trim-and-verify. When `[E2,...,E14]` over-cites a single claim,
keep first N pointers, verify normally, record
POINTER_OVERFLOW_TRIMMED in violations. STRICT becomes unreachable
(audit_mode caps at HYBRID) so the over-cite pattern stays
surfaced — but a correct claim like "Leonardo da Vinci painted
the Mona Lisa." no longer gets nuked for cosmetic over-citation.
Pre-fix: pointer mode hit 0/3 STRICT on Mona Lisa (mega-bracket
triggered SCHEMA_INVALID). Post-fix: HYBRID 2/14 with the right
answer rendered alongside both kept source spans. The dropped
pointers count toward n_quotes so the denominator surfaces the
over-cite to the auditor.
Bench scaffolding: ANSWER_MODES tuple now includes "claim_lattice"
(JSON), Makefile default sweeps all three. Question set expanded
from 8 to 22 covering narrow factoid, broad descriptive, entity
list, relationship, comparison, niche, adversarial, out-of-corpus.
460 tests pass. Connecticut output stays clean (HYBRID 4/7); JP-
dinosaurs pointer mode still UNGROUNDED via the bare-name guard
(model emits one-token entity names, the right floor catches them).
Step-by-step operator guide for standing up an aborist mesh between
two real hosts: pre-flight, init/enable on both peers, out-of-band
pubkey exchange, mutual enrollment, mesh serve, mesh sync, audit
chain integrity checks, eviction protocol, reset/teardown.
Calls out what's not yet wired (mesh pull, per-peer chain merge,
AEAD body encryption) so operators don't expect features that ship
later. Pairs with docs/mesh.md (protocol contract) and the e2e tests
in tests/test_mesh_wire_e2e.py.
Adds docs/mesh.md and five graphviz diagrams covering the federation
layer: identity stack, epoch state machine, per-member secret envelope,
gossip wire contract, and operator decision tree. Pins the protocol
contract for the upcoming HTTP wire (mesh sync, mesh serve).
Makefile gets a 'docs' target with pattern rule so PNG renders are
incremental from .dot sources.