Baseline (b182, pure-persona) showed Donut distills descriptive questions to bare
keywords ("the guy with the roid rage" -> "roid rage"), dropping the entity from her
reference_knowledge results (~6/10 roid-rage runs -> ent@None -> deflect). The query-
formulation instruction now directs her to pass the FULL phrasing, keep the asker's
descriptive words, and enrich toward the likely name/canonical terms rather than boil
down to a bare keyword. Touches only query formulation; the grounding/deflect/near-miss
anti-fabrication rules are unchanged, so it composes with fix A (expand to find, still
ground-or-deflect on what returns). Illustration is a non-fixture example so the
roid-rage and crown fixture cases stay honest generalization measures. The #393
consumer lever, paired with worldtree-dev's reference_knowledge tool directive (a95dc5a).
Refines the anti-fabrication miss-handling into three explicit outcomes: firm recall
(answer, grounded), near-miss (a specific named candidate surfaced weakly -> offer the
NAME the tool returned as a tentative "do you mean X?", never invented detail, confirm
before recalling in full), and true blank (in-character deflect). Previously a weak-but-
named hit was flat-dismissed, throwing away a real lead. The anti-fabrication invariant
is unchanged — she offers only a name the tool truly returned, never invented substance.
Live-patched + verified against b181 (the "dangerous crown" case now names/offers the
Crown of the Sepsis Whore; no firm-hit regression).
Follow-up to 3e12c4d. Operator asked whether Donut should re-search on a LOW-confidence
miss. Tested a bounded reformulated retry live: it BACKFIRES. RRF confidence is inflatable
by any DCC-flavored query, so reformulating a genuine miss (e.g. 'Jack', who is NOT in the
KB — verified: zero fiction rows name a character Jack) into 'Jack Dungeon Crawler Carl'
scores MEDIUM off the OTHER terms and hands her a false grounding to fabricate on. Reverted
to single-search LOW=deflect: Jack now deflects reliably (2/2 runs, in-character), Carl
(MEDIUM, grounded) still answers. A robust retry needs a tool-side does-the-row-name-the-
subject check (Worldtree #389 territory), not a persona-side confidence gate. Also cleaned
a duplicated paragraph from the edit iterations.
The persona previously MANDATED confabulation ("never break character to admit the
records are thin; answer with total confidence"), so on a tool miss Donut filled the
gap from her DCC training knowledge and presented it as grounded recall (operator:
"not make shit up — her searches for Zev and Jack are still misses").
New rule: her memory IS what reference_knowledge returns, nothing else. A MISS = empty
results, LOW confidence, or nothing that actually names the subject → deflect IN
CHARACTER (theatrical dismissal), never a confident fiction, and never fill from
book-knowledge she can't see in the results. Verified live: a fabricated term and a
LOW-confidence real character (Jack) both deflect; MEDIUM+ grounded content (Carl)
still answers. Role header corrected character-rp-reasoning -> thoughtful-character
(the live role).
FOOT-GUN: a live `tier3 patch` does not reliably refresh the running agent context —
delete + define (recreate) is the reliable path to change a live Tier-3 persona.
TTS fixes + hardening for the Donut voiced interview.
Feature:
- gibberish -> pin `language: "en-us"` on every gateway call (DEC-9); the
multilingual model drifted into other-language phonemes without it.
- truncation -> the Zonos model hard-caps one synthesis at 6144 tokens /
71.2s (infra-ops). Chunk client-side (paragraph-first, greedy to ~75%
of cap for prosody; sentence/clause fallback) and concatenate the int16
PCM behind ONE WAV header (DEC-10). /api/tts becomes POST so a long turn
rides the body, not a length-capped URL (DEC-10a).
- persona -> dialogue-only rewrite (no asterisk RP beats -- they were being
voiced as gibberish) + always consult the native `reference_knowledge`
tool before answering (retires the stale kb_bridge references). Pushed
live to ratatoskr:donut.
Heid code-review + bug-hunt hardening (4-arm panels, triaged):
- untrusted /api/tts body fields degrade, never 500: huge-int PAD
(OverflowError), non-str agent_id (unhashable .get), lone surrogates
(utf-8 encode), whitespace-only text.
- serialize lock + client released on every peek escape (cancel /
InvalidURL) -- previously a permanent deadlock.
- a mid-stream drop after a committed 200 degrades (keeps what played),
never raises into the response; a non-WAV 200 body is rejected (RIFF
sniff + bounded header scan) instead of decoded as garbage.
546 tests green; long-form live-verified (106.6s, one header). Contract
brought canonical (DEC-9/10, FN chunk_text/tts_stream_long, POST endpoint,
INV-TTS-4 logging scope, FN pad_to_dials domain). reference_knowledge
empty-recall root-caused to a Worldtree wing-misfile (escalated to
worldtree-dev; not ratatoskr code).
Slice 1 of the auto-TTS/voiced-KB-character build (operator ask "add auto-tts
to the web gui"): the donut_voiced_interview contract (validated), the Princess
Donut persona (corpus-grounded from a Mimir DCC pull), and ratatoskr:donut
defined on :8081 (server-side; in the picker). Slices 2 (Zonos auto-TTS) + 3
(retire-ready KB-bridge) are TO BUILD.
Snapshot captures the full build state + design (Zonos gateway :8890, voice
"donut" registered, affect-driven emotion dials; the worldtree-dev-ruled
consumer-side retrieval + memory_context pinning bridge, retire-ready) for the
post-clear resume, plus the arcs since v0.22.0 (SDK 1.1.2 repin, bifrost 1.1.5,
canonical sync, release-only versioning, the Sindra saga + local-index
schema-burial foot-gun, the Mimir #382 reference-consumer finding). Handoff at
/tmp/ratatoskr-dev-handoff.md. Release-only cadence: no tag.