# Persistent memory — ratatoskr _Last updated: 2026-08-02_ > **Always check for `/tmp/ratatoskr-dev-handoff.md`** — if it exists and its > `Written:` stamp is under an hour old, read it (it carries the in-flight > handoff from the previous session), then delete it. Older than an hour: > stale — delete it unread. This file captures durable intent and supporting evidence (goals, decisions, foot-gun warnings, in-flight state) across context resets. Read it at session start; treat it as one input alongside `CLAUDE.md` and the auto-memory system, not as the single source of truth. When durable state shifts enough to warrant capture, run `/snapshot` and commit alongside the next commit per the persistent-memory commit-along rule in `CLAUDE.md`. --- ## Repo purpose Ratatoskr is a **dev-grade debug-observability TUI** for Worldtree's Conversation API. The product IS the observability surface; chat is the input mechanism. Devs run Ratatoskr against a local Worldtree to watch a turn flow through every layer of the system, side-by-side, in one terminal: agent SSE stream, persona/Vili affect dispatch, tool calls, Bifrost handshake state, admin lifecycle events, optional raw server log. Named after the squirrel that runs up and down Yggdrasil carrying messages between layers. On-the-nose Worldtree resonance (Yggdrasil = the World Tree). **Second identity (since 2026-06-14): the v1 Bifrost Tier-3 consumer/provider** — the durable persistence Worldtree writes Tier-3 agent affect (PAD/persona, `:8390`) + memory (`:8391`) into. Lives in `src/ratatoskr/provider/`, depends on `bifrost` (`provider` optional-extra), separate from the conversation-API spec pin. So ratatoskr now owns BOTH ends of the Bifrost round-trip — the lens #17 exploits. **v0.15.0+ sibling browser surface** (`ratatoskr.web`, `ratatoskr-web` console script): same five-pane debug surface over the same SSE wire, LAN-viewable. Internal-LAN trust model — `0.0.0.0`, no auth/TLS/CORS (operator direction). Disciplined regardless: transcript HTML-escapes assistant content (INV-004); upstream API key stays server-side (INV-003). ## Current state / in-flight _As of 2026-08-01:_ **🔨 Donut voiced-interview — ALL 3 SLICES BUILT + COMMITTED + LIVE-PROVEN (2026-08-01). Heid gates PENDING triage.** Operator ask "add auto-tts to the web gui" grew into a voiced, corpus-grounded Tier-3 interview character. **Slice 1** (persona + `ratatoskr:donut` define, `3e912b1`), **Slice 2** (auto-TTS via Zonos, `1883214`), **Slice 3** (retire-ready KB-recall bridge, `7168914`) — ALL DONE, **531 green**, both live-smoked end-to-end on :8081/b128. Contract `docs/contracts/donut_voiced_interview.contract.md`. **NOT pushed** (operator's call; local at `7168914`). - **Slice 2 (TTS):** `src/ratatoskr/tts.py` (Zonos gateway client + `pad_to_dials`) + `/api/tts` proxy in `web/server.py` (voice map `ratatoskr:donut→donut`, serialize lock, 503 degrade) + `index.html` 🔊 toggle (opt-in, localStorage, default off) / speak-on-`done` / AbortController cancel-on-new-turn / `