# ADR-F12 — Wiki-Compile: Grounded Concept Pages **Status:** IMPL (GO after Spike-Session 2026-06-08; Gate-Fixes 2026-06-14) **Owners:** F-12 Worker (Sonnet) **Last updated:** 2026-06-14 --- ## Context F-12 adds a wiki-compile layer on top of the RAG substrate: for each concept in `wiki/concepts.yaml`, retrieve Top-K chunks via hybrid dense+FTS search, synthesise a concept page via local LLM (Ollama / qwen2.5:7b), and write the result to `wiki/.md`. Primary risk: **hallucination**. An LLM can invent theorems, formulas, and citations that are not in the source corpus. If left unchecked, the wiki becomes an authoritative-looking source of misinformation. Secondary risk: **undetected quarantine escape**. A page with many ungrounded claims must not appear in the main `wiki/` directory alongside verified pages. --- ## Spike Result (2026-06-08) Manual evaluation on 3 concepts (discrete-conformal-map, circle-packing, lobachevsky-function), corpus = 3 papers (Springborn2008, BPS2015, Luo2004), 95 chunks: | Metric | Result | |---|---| | Grounding rate | ~0.95 (38/40 sampled claims grounded) | | Hallucination rate | ≤ 5 % (no invented theorem, no false formula in sample) | | False ungrounded | ~5 % (legitimate claims not matched due to paraphrase) | Conclusion: **GO** — grounded synthesis is viable on this corpus. --- ## Decision ### Grounding Guard (implemented in `codex/wiki.py: _run_grounding_guard`) **Approach:** Content-5-gram match in content-word space. 1. **Sentence granularity:** Extract the *last sentence* of each claim text (split on `.!?`, take the last non-empty fragment). Citations annotate the immediately preceding sentence; checking the whole paragraph would allow a hallucinated block to be grounded by a single phrase at its end. 2. **Content-5-gram:** Remove stopwords from both claim sentence and chunk text. Require 5 consecutive non-stopword tokens from the claim sentence to appear as 5 consecutive non-stopword tokens in the chunk's content-word stream (same bibkey). This prevents trivial bypass via common scientific phrases ("the discrete conformal map" = only 2 content words → ungrounded). 3. **Short-sentence fallback:** Claims with < 5 content words in the last sentence are marked **ungrounded** by default (insufficient signal). **Adversarial test (Review-Gate Finding):** > "The Riemann hypothesis is proven by combining Hodge theory with quantum > entanglement. Furthermore P=NP holds for hyperbolic tetrahedra. > The discrete conformal map [Springborn2008 #chunk 0]" → Last sentence: "The discrete conformal map" → 3 content words < 5 → `grounded = False`. Bypass closed. ### Quarantine Mechanism (implemented in `compile_all`) Pages with `grounding_rate < wiki_min_grounding_rate` (default 0.5) are: - Written to `wiki/draft/.md` instead of `wiki/.md` - Tracked in `CompileReport.quarantined` - Logged as `QUARANTINED` in `wiki/log.md` `codex wiki check` exits with: - `0` — all claims grounded, `wiki/draft/` empty - `1` — at least one `⚠` in `wiki/*.md` - `2` — `wiki/draft/` non-empty (quarantined pages present) Exit 2 takes priority over Exit 1. Config: `WIKI_MIN_GROUNDING_RATE` (env/`.env`), default `0.5`. ### LLM Graceful Degradation `compile_concept` wraps `llm.generate()` in a `try/except`. On any exception (httpx.ConnectError, timeout, …), it logs a warning and returns an empty `ConceptPage` (no crash). An empty page has 0 claims → grounding rate 0.0 → quarantine path. ### Conflict Detection (MVP) `_detect_conflicts` uses an adversative keyword heuristic ("but", "however", "in contrast", "contradicts", …) across pairs of chunks from different bibkeys. Results in `CompileReport.conflicts`. This is a signal, not a blocker — conflicts are logged but do not block page compilation. ### Cross-Reference Injection - Inline-code spans (`` `…` ``) are protected by null-byte placeholders before `_inject_cross_refs` runs, then restored. This prevents concept titles inside code from being rewritten. - `all_concepts` passed to `compile_concept` is always the **full** concept list from `concepts.yaml`, regardless of `--concept` filter. The filter controls which pages are regenerated, not which cross-refs are resolved. --- ## Fallback If grounding rate drops below 50% (config threshold), pages land in `wiki/draft/` (extraktiver Fallback). Human review required before promotion to `wiki/`. For `wiki_min_grounding_rate = 0.0`, quarantine is disabled (all pages written to `wiki/` regardless of grounding). Not recommended for production. --- ## Consequences - R-27 met: Grounding ≥ 90% on spike corpus; Halluzinations-Rate ≤ 5%. - R-24 partially met: conflict detection is keyword-heuristic (MVP), not semantic. Full semantic conflict detection deferred to F-13. - No DB schema changes (F-12 constraint). All state in `wiki/` directory. - Ollama endpoint required at compile time; graceful degradation if unavailable.