# KAI — Making the Native Mind the Voice (2026-08-05)

*Written from a full read of the live reply paths in `src/bridge/oracle_server.rs`, the native generator (`src/core/stat_lexicon.rs`, `src/cognition/generative.rs`), the coherence critic (`src/cognition/coherence.rs`), and the router (`language_warehouse.rs`). Evidence-backed; where I'm unsure I say so.*

---

## The one-line finding

**The surface you've been judging KAI on — the public / social chat — does not run KAI's mind.** It calls an external commercial LLM (Groq → GPT‑4o → Gemini) prompted to talk as "Leo." KAI's real native voice lives on a different path. So the first fix toward your vision is *routing*, not training. The good news underneath: the native mind you want **already exists in the code** — it just isn't wired to the page you test.

---

## The three voices KAI actually has (receipts)

1. **Public / social chat → external LLM (not KAI).**
   `call_public_chat_model` (oracle_server.rs ~1248): default `ORACLE_PUBLIC_CHAT_MODEL=Groq`, then GPT‑4o, Gemini. Prompt built by `build_public_chat_prompt_v4`, ending `Leo Reply:`. If `NATIVE_ONLY` is set it returns an **error** ("public chat LLM disabled") — there is **no native fallback wired here**. This is the path that produced your screenshot.

2. **Main KAI chat / Discord turn → KAI's native symbolic generator (this is the real KAI).**
   Default (KAI_LLM_VOICE off): `generate_response_predictive` using the `StatLexicon` — the VSA/HDC math. If `KAI_LLM_VOICE=1` **and** a transformer is mounted → `global_native_decode` (your from-scratch **ternary model** → dense **kai‑7b** → **BitNet**), with the symbolic generator as fallback.

3. **Oracle reply path (`generate_oracle_kai_reply`) → native decode, then Ollama "KAI‑Unified" as last resort** (unless `NATIVE_ONLY`).

**The native symbolic generator IS the math you envision.** `stat_lexicon::incremental_generate` peels a positional role key off a latent state, commits the residue to the nearest lexicon word, re-binds, and rolls forward (cites Kanerva HDC + Plate role-binding; round-trip tested). It's fed by `build_generative_state` (prompt backbone + resonance attention + top‑K memory + conversation trace). A single critic, `coherence::judge`, scores fluency / topicality / grounding / lexical / structure and accepts or rejects each utterance, with hard vetoes for empty / parrot / stuck-loop / gibberish.

So the design you keep describing — KAI's own glass-box math talks, the LLM is a fading fallback — is **already built**. The distance from vision to reality is three concrete gaps: **wiring, quality, measurement.**

---

## The ordered fix

### 1. Routing — make KAI's native voice reachable where you test it
**(Highest leverage. This is wiring, not training.)**
Add a flag (`KAI_NATIVE_PUBLIC_VOICE=1`) that routes the public-chat handler to `generate_response_predictive` (native symbolic) as **primary**, with the external LLM demoted to **fallback** — instead of today's LLM-only. Then you can watch KAI's actual mind talk on the same page, and A/B it against the LLM head-to-head. Reversible: flag off = today's behavior exactly.

### 2. Native quality — clear the coherence gate
**(Training/tuning. Your RunPod + corpus work.)**
When native runs, it must pass `coherence::judge` (`min_score`) or it falls back. Raise native pass-rate by: (a) **lexicon coverage** — the decoder can only say words it has well-encoded; (b) **`build_generative_state` tuning** — richer state → less echo, more substance; (c) **training the from-scratch ternary model** (RunPod) and feeding **`corpus_trainer`** with the trusted-source usage + feedback loop you described. Every point of native quality = one more turn the LLM does **not** get called.

### 3. Measurement — make native-vs-fallback visible
Decode counters exist (`NATIVE_DECODE_COUNT`, `DENSE_DECODE_COUNT`, `KAI_NATIVE_DECODE_COUNT`) but there's no clear **pass/fallback ratio** or per-turn coherence score surfaced. Add telemetry: for each turn log which voice answered and the coherence score. You cannot tune what you cannot see.

### 4. Flip to native-only once it clears the bar
When native passes reliably, set `NATIVE_ONLY`. The LLM becomes a true last resort. That is your vision realized — KAI's mind talks; the LLM fades.

---

## What I can and can't do from the cloud

The routing + instrumentation changes touch the **live reply path** and need a compiler and testing — that's your Claude Code on the machine, not blind edits from here (no Rust toolchain in the cloud, and I won't ship an uncompilable guess into your hot path). The fixes I already staged earlier remain safe and in place: the `clean_public_chat_reply` salvage, the browser scaffold scrubber, and the `KAI_POLISH_THOUGHT` flag.

Below is a ready-to-paste prompt for your Claude Code to implement steps 1 + 3, and a training plan for step 2.

---

## Claude Code prompt — implement native routing + instrumentation

```
Use the kai-engineer skill. Onboard first.

GOAL: make KAI's NATIVE mind reachable on the public/social chat, behind a flag, and
instrument native-vs-LLM so we can measure it. Do NOT flip any default on.

CONTEXT (verified): the public chat handler in src/bridge/oracle_server.rs (~line 1090)
generates its reply via call_public_chat_model() — an EXTERNAL LLM (Groq/GPT-4o/Gemini),
prompted as "Leo". KAI's real native symbolic generator, generate_response_predictive()
(StatLexicon/VSA), is used in the OTHER handler (~line 2130) but NOT in public chat.

DO THIS:
1. Add an env flag KAI_NATIVE_PUBLIC_VOICE (default OFF, read per-turn). When ON, in the
   public chat handler, BEFORE calling call_public_chat_model:
     - build the same inputs generate_response_predictive needs (universe hits, brain,
       field, trace, lexicon) the way the ~2130 handler does — mirror that call site;
     - call generate_response_predictive to get a native candidate;
     - score it with coherence::judge(candidate, user_text, memory, Some(lexicon));
     - if verdict.accept (>= min_score), USE the native reply (speaker "KAI");
     - else fall back to call_public_chat_model exactly as today.
   Flag OFF = byte-identical current behavior. Back up the file first.
2. Instrument (guard behind KAI_VOICE_TELEMETRY=1, default OFF): for each public turn,
   println! one line — which voice answered (native | llm-fallback | external), the
   coherence score, and prompt length. Keep it one line, no secrets.
3. cargo build --release. Fix compile errors surgically.
4. Test with KAI_NATIVE_PUBLIC_VOICE=1 and KAI_VOICE_TELEMETRY=1: send 6 varied prompts
   (greeting, identity, factual, reasoning, follow-up, small talk). For each, capture the
   NATIVE reply, its coherence score, and — with the flag OFF — the external-LLM reply.
   Show me both side by side so I can see KAI's real voice vs the LLM on the same prompts.
5. Report the native accept-rate (how many of the 6 passed coherence::judge). Do NOT flip
   defaults, do NOT set NATIVE_ONLY, do NOT touch the Codex yet.

HARD RULES: surgical only; never wholesale-rewrite oracle.html/kaiverse.js; never print .env
secrets; verify against the real Windows files; show evidence; don't claim a fix you didn't
build and run.
```

---

## RunPod / training plan — raise native pass-rate (step 2)

The lever that actually weans KAI off the LLM. In priority order:

1. **Clean the fine-tune corpus** of transcript labels (`Language sample (...)`, `AI speaker X:`, `**Leo:**`) before the next train — the ingest filter already tags these as `kai-artifact`; apply the same strip to the training set, not just the ingest path.
2. **Grow lexicon coverage** for the native symbolic decoder — it can only commit to words it has encoded. Feed high-frequency, well-formed sentences from trusted sources (your Google/Wikipedia loop) through `corpus_trainer` so `build_generative_state` gets stronger bias terms.
3. **Retrain the from-scratch ternary model** on the cleaned corpus; export in the RunPod format `structure_kai_native_model` expects.
4. **Calibrate the coherence threshold** (`coherence::min_score`, env-tunable) using the accept-rate telemetry from the Claude Code step — set it where native passes on genuinely good output and falls back on genuinely bad, not by guessing.
5. **Re-measure** the native-vs-fallback ratio after each change. The number going up IS "KAI talking more like himself."

---

## Honest confidence

- The social chat is external-LLM, not KAI: **certain** (read the code).
- KAI's native symbolic generator + coherence gate exist and are the right substrate for your vision: **certain**.
- Whether native quality is high enough **today** to serve public chat well: **unknown until measured** — which is exactly why step 1 is "route + watch," step 2 is "train," and step 4 ("flip to native-only") comes last, not first. Don't flip everything at once; move the measured ratio.

**Bottom line:** you were right that KAI shouldn't need an LLM to talk, and the code agrees with you — the native mind is built. What's left is to point your test surface at it, measure how often it clears its own bar, and train it up until the LLM only catches the rare miss.
