memory: snapshot — dots-tts + config-voices/two-voice split shipped; WT #401 personal-WT deadlock routed
Captures this session's durable state: the RP-voice rebuild (chatterbox->dots v0.22.2, config-driven voices + two-voice dialogue/narration split v0.22.3) and the personal WT :8081 deadlock recovery + root-cause routing to worldtree-dev (WT #401). New substrate foot-guns: dots :8198 is a fleet switchboard, dots' language validator is an alias-mapper, per-origin TTS toggle, WT hang signature, dots-streaming-pcm-not-headerless. Three detail files added under persistent-memory.d/.
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
`[2026-08-11]` **TTS migrated chatterbox-fast → dots-tts (v0.22.2, `38b78d8`).**
|
||||||
|
|
||||||
|
Operator-directed after an infra-ops A/B win ("very good"). dots-tts = rednote-hilab
|
||||||
|
`dots.tts-soar` on irv-ml1, replacing chatterbox-fast. `tts.py` stays the single swap seam.
|
||||||
|
|
||||||
|
**Deltas (everything else — streaming placeholder-header WAV shape, browser Web-Audio PCM
|
||||||
|
decode, POST `/api/tts`, the DEC-5 serialize lock, INV-TTS-1..4 — unchanged):**
|
||||||
|
- **Gateway body OpenAI-shaped:** `{input, voice, response_format:"wav", stream:true}` —
|
||||||
|
`input` not chatterbox's `text`, `response_format` not `format`. Closer to the Zonos-era
|
||||||
|
client. `DOTS_TTS_URL = http://10.100.79.3:8198/v1/audio/speech` replaced `CHATTERBOX_TTS_URL`.
|
||||||
|
- **Sample rate 24000 → 48000 Hz** (browser `SR = 48000` in `index.html`, else ~2× too fast).
|
||||||
|
- **Default voice `glados_25s` → `glados`** (dots voices: donut/glados/emmie/miranda). donut carries over.
|
||||||
|
- **Serialized single-consumer** — dots renders one generation at a time; satisfied by the
|
||||||
|
existing DEC-5 lock, no code change.
|
||||||
|
- **Affect stays dropped** (DEC-7): dots has no emotion knob, same as chatterbox — NOT a fresh loss.
|
||||||
|
|
||||||
|
Live-verified end-to-end on `:8765` (RIFF/WAVE 48kHz mono s16le through `/api/tts`); 520 tests
|
||||||
|
green. Contract `donut_voiced_interview.contract.md` amended (migration banner + DEC-1/3/8/9a +
|
||||||
|
FN blocks). chatterbox-fast `:8197` kept as rollback, then reclaimed by infra-ops once
|
||||||
|
operator ear-confirmed. Superseded next day by config-driven voices (see
|
||||||
|
[[2026-08-12-config-voices-two-voice]]).
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
`[2026-08-12]` **Config-driven voices + two-voice dialogue/narration split SHIPPED (v0.22.3, `5c3d0ad`).**
|
||||||
|
|
||||||
|
Operator ask: "we need rata side config of voices too" + "tempted to do two voices — one for
|
||||||
|
dialogue, one for non-dialogue." Chose (via AskUserQuestion) "config + two-voice together now."
|
||||||
|
|
||||||
|
**Config (retires the hardcoded `_TTS_VOICE_MAP`):** `~/.config/ratatoskr/voices.json`, beside
|
||||||
|
`local_agents.json`/`provider.env` (NOT folded into the agent-index schema — isolated from its
|
||||||
|
v1→v2 silent-drop foot-gun). Schema:
|
||||||
|
`{"default":"<v>","agents":{"<agent_id>":{"voice":"<v>","narration_voice":"<v>"?}}}`. Absent/malformed
|
||||||
|
→ built-in `DEFAULT_VOICE_CONFIG`, logged, never crashes (INV-TTS-5). Initial: donut→donut;
|
||||||
|
sindra→miranda dialogue + emmie narration.
|
||||||
|
|
||||||
|
**Two-voice = the presence of `narration_voice` is the split switch** (dropped the operator's
|
||||||
|
proposed `dialogue_only` flag — an agent with no narration_voice is single-voice, which is why
|
||||||
|
dialogue-only Donut needs no special-casing). `segment_dialogue` splits on quotes (straight `"`
|
||||||
|
+ curly `“ ”`; apostrophes never split a word): quoted = dialogue → `voice`, rest = narration →
|
||||||
|
`narration_voice`. Known limit: if a mixed persona speaks WITHOUT quotes, it reads as narration.
|
||||||
|
|
||||||
|
**Synthesis (`tts_stream_stitched` replaced `tts_stream`):** spans synth SERIALLY (dots
|
||||||
|
single-consumer), span 0 verbatim (wav header+PCM), spans 1..N header-stripped
|
||||||
|
(accumulate-until-`data`) → one gapless 48kHz stream with a single leading header (INV-TTS-7).
|
||||||
|
A single-span list is a byte-identical passthrough (INV-TTS-6, no single-voice regression). NOTE
|
||||||
|
the dots-pcm-not-headless-in-stream foot-gun that forced this design (see Tried and abandoned).
|
||||||
|
|
||||||
|
New module `src/ratatoskr/voices.py` (`load_voice_config` / `segment_dialogue` /
|
||||||
|
`resolve_voice_spans`); `create_app` gains `voice_config`; `entrypoint` loads it. Contract DEC-11
|
||||||
|
+ INV-TTS-5/6/7; new `tests/test_voices.py`. **545 tests green**, new code ruff-clean. Discipline:
|
||||||
|
contract-first + TDD + seam-check + local bug-hunt + live-verify; heid async gates SKIPPED
|
||||||
|
(offered). Live-verified on `:8765`: Sindra mixed turn → 2 dots calls (emmie+miranda) stitched to
|
||||||
|
one 48kHz WAV (single RIFF header); Donut single-voice unchanged. Cut as **patch** (self-contained
|
||||||
|
feature, no downstream coordination → patch-defensible → tie-break to patch; operator declined the
|
||||||
|
v0.23.0-minor option by saying "push it"). Builds on [[2026-08-11-tts-dots-migration]].
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
`[2026-08-12]` **Personal WT :8081 deadlocked after ~4 days → routed to worldtree-dev as WT #401.**
|
||||||
|
|
||||||
|
Operator hit "failed to load agents" in the web console + asked "does the server need
|
||||||
|
restarting?" Diagnosed: NOT ratatoskr. The personal Worldtree at `10.250.50.152:8081`
|
||||||
|
(`worldtree-personal-worldtree-api-1`, "Up 4 days (unhealthy)") was HUNG — TCP port open (accepts
|
||||||
|
connections) but the app answered NOTHING: `/health`, `/agents`, `/capabilities` all returned
|
||||||
|
`000` (accept-then-drop, "Server disconnected without sending a response"). Classic dead/deadlocked
|
||||||
|
event loop behind a live socket.
|
||||||
|
|
||||||
|
**Ratatoskr behaved correctly:** `/api/agents` was 12/12 502 `network_error` on the dead
|
||||||
|
upstream (the endpoint's `except (httpx.RequestError, ConnectFailed) → 502`), and auto-recovered
|
||||||
|
to 8/8 200 (donut+sindra back) the instant WT answered — NO ratatoskr restart. Restarting
|
||||||
|
ratatoskr would only have 502'd against the same dead upstream + dropped the session.
|
||||||
|
|
||||||
|
**Recovery + routing:** operator greenlit → I pinged infra-ops (uptime lane). They `docker
|
||||||
|
restart`'d it (same image, no recreate; demo `:8080` + pinned `:8082` untouched); `/health`
|
||||||
|
recovered 000→200 at ~45s. Operator greenlit root-cause → routed to worldtree-dev, tracked as
|
||||||
|
**WT #401** (diagnose-first). infra-ops froze the full 4-day container log (55MB / 647k lines,
|
||||||
|
`2026-08-08T22:15Z`→restart) to host-fs (`nh3-dev:/var/tmp/worldtree-401/`) since the docker
|
||||||
|
health buffer had already rolled.
|
||||||
|
|
||||||
|
**Smoking gun (infra-ops, from the app log):** last good `/health` at `22:00:26Z`; the dying
|
||||||
|
worker's LAST line = a sqlite **"unable to open database file"** traceback in the
|
||||||
|
**`context_promotion` ledger** at `22:09:38Z`. No OOM, disk not full. worldtree-dev's read: a
|
||||||
|
background/idle promotion job made an untimed synchronous sqlite call that wedged the event loop
|
||||||
|
(no user turn in flight; abrupt serving→silent in <60s; ~0.1s connection drops = accept queue
|
||||||
|
serviced but handler coroutines never scheduled). Consumer-side data I gave #401: today's :8081
|
||||||
|
load was light + fully sequential, and TTS synthesis offloads to dots `:8198` (added ~zero :8081
|
||||||
|
load). **Root-cause is worldtree-dev's; I owe them only a consumer-side repro if they ask.**
|
||||||
|
The hang-signature is now a substrate foot-gun (see Current state).
|
||||||
+13
-8
@@ -1,6 +1,6 @@
|
|||||||
# Persistent memory — ratatoskr
|
# Persistent memory — ratatoskr
|
||||||
|
|
||||||
_Last updated: 2026-08-09_
|
_Last updated: 2026-08-13_
|
||||||
|
|
||||||
> **Always check for `/tmp/ratatoskr-dev-handoff.md`** — if it exists and its
|
> **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
|
> `Written:` stamp is under an hour old, read it (it carries the in-flight
|
||||||
@@ -44,23 +44,27 @@ upstream API key stays server-side (INV-003).
|
|||||||
|
|
||||||
## Current state / in-flight
|
## Current state / in-flight
|
||||||
|
|
||||||
_As of 2026-08-09:_
|
_As of 2026-08-13:_
|
||||||
|
|
||||||
**Nothing in flight on ratatoskr's side — this session's three arcs all shipped + pushed (HEAD `93011dc`, origin synced). The live tails are all upstream (worldtree-dev), not ours.** Details in Recent decisions; the durable substrate below.
|
**Nothing in flight on ratatoskr's side. The RP-voice stack was rebuilt this session (chatterbox→dots, then config-driven voices + a two-voice dialogue/narration split) — all shipped + PUSHED (HEAD `5c3d0ad`, origin synced, tags `v0.22.2`/`v0.22.3`). The one open tail is upstream: WT #401 (worldtree-dev owns the personal-WT deadlock root-cause).** Details in Recent decisions; durable substrate below.
|
||||||
|
|
||||||
- **TTS migrated Zonos→chatterbox-fast + German-drift fixed** — live on `ratatoskr-web` **pid 2214344** (`:8765`). `tts.py` is the single swap seam: chatterbox-fast `http://10.100.79.3:8197/tts`, bespoke `{text,voice,format,stream}`, 24kHz, NO affect, NO client chunking (`RATATOSKR_TTS_URL` overrides). Drift fixed server-side (chatterbox `:v2` `max_chunk_chars=250`); consumer sends full text + default sampling. FOOT-GUN: `ratatoskr-web` is a bare detached process, no supervisor → re-stales on reboot/crash; systemd unit offered, operator declined.
|
- **TTS = dots-tts + config-driven voices + two-voice split** — live on `ratatoskr-web` **pid 2290701** (`:8765`, dots + `voices.json` loaded). Backend is **dots-tts** via the fleet **switchboard** `http://10.100.79.3:8198/v1/audio/speech` (OpenAI-shaped `{input,voice,response_format,stream}`, 48kHz mono s16le, streaming placeholder-header WAV). `tts.py` is the single swap seam (`RATATOSKR_TTS_URL` overrides), NO affect. Per-agent voices live in **`~/.config/ratatoskr/voices.json`** (donut→donut single; sindra→miranda dialogue + emmie narration); an agent with a `narration_voice` gets the quote-split two-voice stitch (`tts_stream_stitched`, `src/ratatoskr/voices.py`).
|
||||||
- **Crown-recall arc CLOSED** (b185 identity-anchor rerank enrichment; gate verdict 79%→12% stress miss). Upstream tail: b185 promotion beyond personal/demo. If the operator ever pulls a prompt-side lever at the bare-query/adoption residual (the irreducible ceiling shared with #397), worldtree-dev asks us to re-point the gate.
|
- **Personal WT :8081 recovered + root-cause routed to WT #401** — it deadlocked after ~4 days (event-loop wedge from a background `context_promotion` sqlite error); infra-ops `docker restart`'d it, worldtree-dev owns the diagnosis. Ratatoskr auto-recovered (degrade path held; no ratatoskr restart). Only possible follow-up = a consumer-side repro if worldtree-dev asks.
|
||||||
- **Two diagnostic gates in-repo** — `docs/diagnostics/lexical_recall_gate.py` (exact-term recall class instrument) + `temporal_order_gate.py` (#397 order_by=chapter). The before/after instruments for any future retrieval lever; #397 CLOSED, #400 closes on brokkr's no-harm post-half.
|
|
||||||
|
|
||||||
**Deferred / queued (non-urgent, pre-existing — tracked, NOT this-session):** TUI rip (`tui.py`+`tests/test_tui.py` delete cleanly, but `cli.py` is SHARED — relocate `USER_AGENT`/`ParsedArgs`/`_format_*` first; breaking public-surface removal → minor bump, operator approval); #368 backfill live-verify (synthetic legacy corpus); SDK **#371** (Rata = seed donor + future consumer; next = WT codegen spike; Rata's repin rides the later Python milestone; divergences D-1 unknown-SSE-skip / D-2 open-world-enums / D-3 typed-410); P06 referential-frame A/B/C probe (waits WT b122); R39 Phase-2 matched-quartets (confirmatory); bifrost snapshot-cursor adoption (normative, non-blocking).
|
**Deferred / queued (non-urgent, pre-existing — tracked, NOT this-session):** heid gates on the two-voice feature SKIPPED in-session (offered, not run — optional cross-frontier gate if wanted); TUI rip (`tui.py`+`tests/test_tui.py` delete cleanly, but `cli.py` is SHARED — relocate `USER_AGENT`/`ParsedArgs`/`_format_*` first; breaking public-surface removal → minor bump, operator approval); #368 backfill live-verify (synthetic legacy corpus); SDK **#371** (Rata = seed donor + future consumer; next = WT codegen spike; divergences D-1 unknown-SSE-skip / D-2 open-world-enums / D-3 typed-410); P06 referential-frame A/B/C probe (waits WT b122); R39 Phase-2 matched-quartets (confirmatory); bifrost snapshot-cursor adoption (normative, non-blocking).
|
||||||
|
|
||||||
**Live substrate / foot-guns:** branch `main`, HEAD `93011dc` pushed; origin `git@gitea.phasefinal.com:vh/ratatoskr.git`. Deps: **`worldtree-sdk==1.2.0`** (gitea PyPI, `[tool.uv.sources]`; new `SseResponseTooLarge` at the stream surfaces), **`bifrost==1.1.5`**/wire v0.7, WT openapi vendored 2.3.0, conversation-api-spec v1.1. **`uv sync --all-extras`** — dev deps are a `[project.optional-dependencies]` EXTRA; plain `uv sync` PRUNES pytest/respx. Personal WT on **b185** (`http://10.250.50.152:8081`, both instances). Surfaces: combined **`:8392`** provider (memory+affect) + **`:8765`** web — detached background processes; `env.sh` sets the REQUIRED `RATATOSKR_MEMORY_EMBEDDING_DIM=1024`; keys mode-600 in `~/.config/ratatoskr/provider.env` + `RATATOSKR_ADMIN_API_KEY`. **FOOT-GUN: check owner-scoped agents via `GET /agents/<owner>:<name>` with the OWNER key (`WORLDTREE_API_KEY`), NOT the admin key (admin → false 404).** SDK-adapter foot-guns (cumulative): SDK reads = open-world dicts → presenters degrade-not-crash at 3 guard levels; all transport failures → `ConnectFailed(status=0)` (every caller `except ConnectFailed`); `local_agents` index v1→v2 bump SILENTLY DROPS pre-cutover agents (`load_local_agents` returns [] on version mismatch). `graphify-out/` runs dirty (auto-regen on commit hook, never stage). v1 = full Worldtree I/O coverage, cuts when WT tags 1.0 (`docs/coverage-map.md`).
|
**Live substrate / foot-guns:** branch `main`, HEAD `5c3d0ad` PUSHED; origin `git@gitea.phasefinal.com:vh/ratatoskr.git`; version **v0.22.3**. Deps: **`worldtree-sdk==1.2.0`**, **`bifrost==1.1.5`**/wire v0.7, WT openapi vendored 2.3.0, conversation-api-spec v1.1. **`uv sync --all-extras`** — dev deps are a `[project.optional-dependencies]` EXTRA; plain `uv sync` PRUNES pytest/respx. Personal WT on **b185** (`http://10.250.50.152:8081`) — **FOOT-GUN: it can deadlock into a live-socket/dead-worker hang (WT #401); symptom = TCP port open but ALL routes return 000 ("server disconnected without response"); fix = infra-ops `docker restart`, ratatoskr auto-recovers.** Surfaces: combined **`:8392`** provider (memory+affect) + **`:8765`** web (pid 2290701) — detached bare processes, no supervisor → re-stale on reboot (relaunch `source env.sh && setsid .venv/bin/ratatoskr-web --host 0.0.0.0 --port 8765`); `env.sh` sets REQUIRED `RATATOSKR_MEMORY_EMBEDDING_DIM=1024`; keys mode-600 in `~/.config/ratatoskr/provider.env`. **dots-tts `:8198` is now a fleet SWITCHBOARD** (fronts dots on `:8202`; +3.3ms; engine swaps = instant `.env` flips; v4 engine adds an optional `language` field). **FOOT-GUN: dots' `language` validator is an alias-mapper NOT a gatekeeper** — word-junk ('klingon') maps to a tag + generates; only structurally-invalid tokens (empty/punctuation/overlong) 400 → validate ourselves if we ever send `language`. **FOOT-GUN: browser auto-TTS is opt-in (`localStorage['ratatoskr-tts']='1'`), PER-ORIGIN** — localhost vs LAN-IP have separate storage, so the toggle doesn't carry between them. **FOOT-GUN: check owner-scoped agents via `GET /agents/<owner>:<name>` with the OWNER key, NOT admin (admin → false 404).** SDK-adapter foot-guns (cumulative): SDK reads = open-world dicts → presenters degrade-not-crash at 3 guard levels; all transport failures → `ConnectFailed(status=0)`; `local_agents` index v1→v2 SILENTLY DROPS pre-cutover agents. `graphify-out/` runs dirty (never stage). v1 = full Worldtree I/O coverage (`docs/coverage-map.md`).
|
||||||
|
|
||||||
## Recent decisions
|
## Recent decisions
|
||||||
|
|
||||||
Chronological log of decisions with `[YYYY-MM-DD]` prefix. One line per
|
Chronological log of decisions with `[YYYY-MM-DD]` prefix. One line per
|
||||||
decision. Captures rationale that won't be obvious from code alone.
|
decision. Captures rationale that won't be obvious from code alone.
|
||||||
|
|
||||||
|
- `[2026-08-12]` **Personal WT :8081 deadlocked after ~4 days → routed to worldtree-dev as WT #401; ratatoskr degrade path held.** Live-socket/dead-worker event-loop wedge (background `context_promotion` sqlite "unable to open database file"); recovered by infra-ops `docker restart`; ratatoskr auto-recovered (12/12 502 → 8/8 200, no ratatoskr restart). → `persistent-memory.d/2026-08-12-wt-401-personal-deadlock.md`
|
||||||
|
- `[2026-08-12]` **Config-driven voices + two-voice dialogue/narration split SHIPPED (v0.22.3, `5c3d0ad`).** `~/.config/ratatoskr/voices.json` (per-agent voice + optional `narration_voice`); new `src/ratatoskr/voices.py`; `tts_stream_stitched` replaces `tts_stream`; contract DEC-11 + INV-TTS-5/6/7. → `persistent-memory.d/2026-08-12-config-voices-two-voice.md`
|
||||||
|
- `[2026-08-12]` **dots-tts `:8198` became a fleet SWITCHBOARD (fronts dots `:8202`, +3.3ms); engine swaps are now instant `.env` flips.** v4 engine adds an optional `language` field; byte-compatible, no ratatoskr change. FOOT-GUN: dots' `language` validator is an alias-mapper not a gatekeeper (word-junk generates, doesn't 400) — validate ourselves if we ever send it.
|
||||||
|
- `[2026-08-11]` **Sindra voiced with the dots `miranda` voice (`3e69bc9`, no bump).** Ratatoskr-side per-agent voice map (resolved at `/api/tts` by `agent_id`); superseded next day by the config-driven map (DEC-11).
|
||||||
|
- `[2026-08-11]` **TTS migrated chatterbox-fast→dots-tts (v0.22.2, `38b78d8`), operator-directed after an A/B win.** OpenAI-shaped `/v1/audio/speech`, SR 24000→48000, default voice glados_25s→glados, serialized single-consumer; affect stays dropped; chatterbox `:8197` reclaimed. → `persistent-memory.d/2026-08-11-tts-dots-migration.md`
|
||||||
- `[2026-08-08]` **Crown-recall RESOLVED at b185 — identity-anchor rerank enrichment closed the class (gate: 79%→12% stress miss).** worldtree-dev shipped a rerank-input identity anchor (from character/terms metadata) + chain-wide tie-determinism (`50ecec7`) instead of the floor lever; `lexical_recall_gate --anchor crown --runs=8` at b185 = 12% miss / 0% knife-edge / item @rank 0 (vs 79% post-fold b184). Floor packet does NOT reopen; 12% residual = bare-query formulation ceiling. Arc complete our side; efficacy delta on WT #400.
|
- `[2026-08-08]` **Crown-recall RESOLVED at b185 — identity-anchor rerank enrichment closed the class (gate: 79%→12% stress miss).** worldtree-dev shipped a rerank-input identity anchor (from character/terms metadata) + chain-wide tie-determinism (`50ecec7`) instead of the floor lever; `lexical_recall_gate --anchor crown --runs=8` at b185 = 12% miss / 0% knife-edge / item @rank 0 (vs 79% post-fold b184). Floor packet does NOT reopen; 12% residual = bare-query formulation ceiling. Arc complete our side; efficacy delta on WT #400.
|
||||||
- `[2026-08-07]` **Crown-recall traced to a general RETRIEVAL-CLASS limitation (exact-lexical match on an indexed surface form buried by dense-semantic neighbors), NOT persona/extraction/synonymy.** worldtree-dev decomposition (WT #400): no-stemming tokenizer + RRF top-10 knife-edge + reranker ownership-demotion. Operator-greenlit evidence-gated sequence (ship stemming fold → gate measures residual → hold `rerank_hybrid_floor` lever). Shipped `docs/diagnostics/lexical_recall_gate.py` (class acceptance instrument); pre-fold baseline control 0% / stress[crown] 100% miss. Awaiting worldtree-dev fold+#397 deploy ping for the pre/post delta. Thread `01KZETD98T`; siblings WT #399 (filed), #397 (committed, not deployed).
|
- `[2026-08-07]` **Crown-recall traced to a general RETRIEVAL-CLASS limitation (exact-lexical match on an indexed surface form buried by dense-semantic neighbors), NOT persona/extraction/synonymy.** worldtree-dev decomposition (WT #400): no-stemming tokenizer + RRF top-10 knife-edge + reranker ownership-demotion. Operator-greenlit evidence-gated sequence (ship stemming fold → gate measures residual → hold `rerank_hybrid_floor` lever). Shipped `docs/diagnostics/lexical_recall_gate.py` (class acceptance instrument); pre-fold baseline control 0% / stress[crown] 100% miss. Awaiting worldtree-dev fold+#397 deploy ping for the pre/post delta. Thread `01KZETD98T`; siblings WT #399 (filed), #397 (committed, not deployed).
|
||||||
- `[2026-08-07]` **TTS migrated Zonos→chatterbox-fast (`:8197` bespoke schema); affect DROPPED (Turbo has no emotion knob, operator "drop it for chatterbox"), client-chunking DROPPED (no per-synth cap), language pin DROPPED, browser SR 44100→24000.** Pushed `19b499a`. English "German drift" real cause (after 2 wrong hypotheses) = Turbo model OVER-RUNS its generation TAIL on long single generations (garble in final ~2-3s, ZCR 1.58x); **fixed SERVER-SIDE by infra-ops (`max_chunk_chars=250`, image :v2, operator ear-confirmed).** Consumer: **REVERTED my interim `top_k/top_p/temp` curbs** (they made it WORSE — pulled garble onset earlier), send full text + default sampling; KEPT the `/api/tts` empty-200→503 guard as hygiene. Contract `donut_voiced_interview.contract.md` amended. Loop closed.
|
- `[2026-08-07]` **TTS migrated Zonos→chatterbox-fast (`:8197` bespoke schema); affect DROPPED (Turbo has no emotion knob, operator "drop it for chatterbox"), client-chunking DROPPED (no per-synth cap), language pin DROPPED, browser SR 44100→24000.** Pushed `19b499a`. English "German drift" real cause (after 2 wrong hypotheses) = Turbo model OVER-RUNS its generation TAIL on long single generations (garble in final ~2-3s, ZCR 1.58x); **fixed SERVER-SIDE by infra-ops (`max_chunk_chars=250`, image :v2, operator ear-confirmed).** Consumer: **REVERTED my interim `top_k/top_p/temp` curbs** (they made it WORSE — pulled garble onset earlier), send full text + default sampling; KEPT the `/api/tts` empty-200→503 guard as hygiene. Contract `donut_voiced_interview.contract.md` amended. Loop closed.
|
||||||
@@ -233,6 +237,7 @@ _For per-issue TDD implementation notes, Volva findings, and contract amendments
|
|||||||
Log of approaches that were tried and rejected, with rationale. Future-self
|
Log of approaches that were tried and rejected, with rationale. Future-self
|
||||||
defense against re-attempting the same cul-de-sac.
|
defense against re-attempting the same cul-de-sac.
|
||||||
|
|
||||||
|
- `[2026-08-11]` **dots streaming `pcm` is NOT headerless — only NON-stream `pcm` is raw s16le.** `response_format:"pcm"` + `stream:true` still emits a RIFF placeholder-header WAV (dots always headers a stream). So the two-voice stitch (`tts_stream_stitched`) can't use "pcm for spans 2..N" to skip header-stripping — it streams every span as `wav` and strips the leading header on later spans (accumulate-until-`data`, INV-TTS-7). Don't chase the pcm shortcut for streaming.
|
||||||
- `[2026-07-10]` **Reverting our provider to bifrost 1.0.0 to fix the bound-handshake `schema_validation_failed` — DISPROVEN, and it would've been the WRONG state** → `persistent-memory.d/2026-07-10-reverting-our-provider-to-bifrost-1-0-0-to-fi.md`
|
- `[2026-07-10]` **Reverting our provider to bifrost 1.0.0 to fix the bound-handshake `schema_validation_failed` — DISPROVEN, and it would've been the WRONG state** → `persistent-memory.d/2026-07-10-reverting-our-provider-to-bifrost-1-0-0-to-fi.md`
|
||||||
- `[2026-06-15]` **Canonical sync retired the issue-scoped parser staleness.** `contract_parser.py` synced to v2.1 (commit `d85ab43`): now validates issue-scoped frontmatter + four v2.1 test categories. The old "treat parser ERROR-on-issue-scoped as expected" note no longer applies.
|
- `[2026-06-15]` **Canonical sync retired the issue-scoped parser staleness.** `contract_parser.py` synced to v2.1 (commit `d85ab43`): now validates issue-scoped frontmatter + four v2.1 test categories. The old "treat parser ERROR-on-issue-scoped as expected" note no longer applies.
|
||||||
- `[2026-06-15]` **Issue #17 filed.** REVERSES design-brief §6's "no Bifrost-binding consumer support" — that negative clause predates ratatoskr's provider identity (2026-06-14), so the canary now owns both ends but its client couldn't drive its own provider. (Shipped 2026-06-18.)
|
- `[2026-06-15]` **Issue #17 filed.** REVERSES design-brief §6's "no Bifrost-binding consumer support" — that negative clause predates ratatoskr's provider identity (2026-06-14), so the canary now owns both ends but its client couldn't drive its own provider. (Shipped 2026-06-18.)
|
||||||
|
|||||||
Reference in New Issue
Block a user