memory: /snapshot — Donut long-form TTS + English pin + dialogue-only shipped (d59f907)
reference_knowledge empty-recall root-caused to a Worldtree fiction/main wing-misfile; worldtree-dev ruled DCC re-ingest into fiction, execution queued next session (post-fix verify offer standing). worldtree-sdk 1.2.0 repin deferred. Filed #21 (sibling JSON-500).
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
`[2026-08-02]` **Donut TTS: English pin + long-form chunking + POST + dialogue-only persona + both heid gates — shipped `d59f907` (pushed).**
|
||||||
|
|
||||||
|
Operator reported two symptoms: Donut's voice "occasionally goes to gibberish" and "truncates on long streams." Both root-caused and fixed, then a mid-work persona directive folded in, then the full House Code Discipline (both heid gates) run.
|
||||||
|
|
||||||
|
## Gibberish → DEC-9 English pin
|
||||||
|
The Zonos gateway (`/v1/audio/speech`, irv-ml1 :8890) is multilingual and takes a `language` field we were never sending → it drifted into other-language phonemes on names/numerics/long spans. Fix: `gateway_body` pins `language:"en-us"` on every call (`_TTS_LANGUAGE`). Verified the gateway accepts it live. The persona rewrite (below) killed the OTHER gibberish vector — the old prompt MANDATED asterisk RP action beats (`*she flicks her tail*`), which were being fed to the engine verbatim.
|
||||||
|
|
||||||
|
## Truncation → DEC-10 client-side chunk-and-concatenate
|
||||||
|
Empirically characterized + confirmed by infra-ops (recipe thread `01KZ1FKX…`): the Zonos model hard-caps ONE synthesis at `max_tokens=6144` = **71.2s of audio** (6144 / 86.3Hz codec frame rate). CRITICAL physics (infra-ops correction): 86.3Hz is a **delivery-independent constant** — 6144 tokens is ALWAYS 71.2s regardless of emotion/rate; emotion changes how many WORDS land in 71.2s, not seconds-per-token. `max_tokens>6144` → HTTP 400 (architectural sequence limit, unraisable). Our old 2000-char cap was LARGER than one call could voice (~750-900 chars), so the gateway truncated first, mid-stream, at ~58-71s.
|
||||||
|
Fix (`tts.py`): `chunk_text(text, budget=747)` — paragraph-first greedy pack (seams on blank lines), sentence fallback for oversized paragraphs, clause(`, ; :`)/word sub-split for oversized sentences; budget = 71.2s×0.75×14c/s (operator: "greedy to 75% of cap for prosody"; the 25% headroom absorbs char→audio-seconds variance). `tts_stream_long` synthesizes each chunk (identical voice+dials+language) and concatenates: chunk 1 verbatim (WAV header + PCM), chunks 2..N header-stripped (`_pcm_after_header`) → ONE continuous int16-PCM stream (infra-ops: never bury a RIFF header mid-stream). `/api/tts` became **POST** (DEC-10a) so the full long text rides the body, not a length-capped GET URL; outer cap 2000→8000 (a shared-3090 hold bound now, not a URL bound). Live-proven: 1978 chars → 3 balanced chunks → 106.6s, one header, clean concatenation — ceiling broken.
|
||||||
|
|
||||||
|
## Persona → dialogue-only + always-consult-the-tool
|
||||||
|
Operator directive mid-work. Rewrote `docs/characters/donut.md` and live-patched `ratatoskr:donut` (via `python -m ratatoskr.tier3 patch`): (a) ONLY spoken dialogue — no stage directions / asterisks / emoji / markdown (preserves her theatrical VOICE, strips narrated ACTION — the TTS-gibberish source); (b) ALWAYS call `reference_knowledge` before answering any question. Note: the tool-call-first is PROMPT-LEVEL only — the define surface (`{agent_name, role, system_prompt}`) exposes no tool_choice, so a hard guarantee would need a WT-side forced-tool capability. Fixed stale drift: the doc still described the retired `kb_bridge`/`[MEMORY:DATA]` pinning. Live-verified: her first event was `reference_knowledge{query}`, output was 0-asterisk dialogue.
|
||||||
|
|
||||||
|
## Both heid gates (4-arm panels: Gróa/Hulda/Regin/Kimi)
|
||||||
|
Dispatched in parallel (code-review thread `01KZ21MC…`, bug-hunt `01KZ21RN…`). The GET→POST switch had re-opened untrusted-type paths that string-only query params masked — all four arms converged. Fixed:
|
||||||
|
- **Untrusted /api/tts body fields degrade, never 500:** huge-int PAD (`float()` OverflowError, not caught by `except ValueError` — routed through the hardened `PadState.from_obj`); non-str `agent_id` (unhashable `dict.get` TypeError — `isinstance(str)` guard); lone surrogate in text (rides JSON as `\udXXX`, `UnicodeEncodeError` on httpx's utf-8 encode of the gateway body — scrubbed via `encode("utf-8","ignore")`); whitespace-only text (empty 200 → 400 via `strip()`).
|
||||||
|
- **Lock+client leak on peek escape** (was a PERMANENT deadlock — a browser abort/CancelledError or `httpx.InvalidURL` before byte 1 escaped the two narrow `except` arms; the `finally` only existed once `piped()` ran): `except BaseException: await _release(); raise` around the peek.
|
||||||
|
- **A2 (net-new):** a mid-stream drop AFTER the 200 committed raised into the response (httpx wraps `aiter_bytes` in `except RequestError`, so a mid-stream drop arrives as `TtsUnavailable`, and the old `if i==0: raise` fired post-commit). Fixed with a `yielded_any` pivot: pre-first-byte failure → raise (→503), post-first-byte failure (any chunk) → degrade+log.
|
||||||
|
- **A3:** non-WAV 200 body forwarded as audio/wav (browser decodes markup as PCM): RIFF-sniff the peeked first bytes → 503; bounded `_pcm_after_header` scan (1KiB) + browser 64KiB acc bound.
|
||||||
|
- Contract brought canonical: DEC-9/10, FN chunk_text/tts_stream_long/tts_endpoint (POST), INV-TTS-4 logging scope, FN pad_to_dials domain, FN client:speakOnDone (POST+8000).
|
||||||
|
Triaged OUT: refuted Hulda's `UnicodeDecodeError`-escapes (it IS a `ValueError` subclass, already caught — Regin confirmed); Regin self-retracted a false `_hard_wrap` finding; accepted the char→token proxy (documented + infra-ops-blessed). Deferred (unchanged sibling handlers): `_create_session`/`_submit_turn` 500 on malformed JSON → filed as issue **#21**.
|
||||||
|
|
||||||
|
+14 regression tests across the two gates; 546 green; committed + pushed `d59f907`.
|
||||||
|
|
||||||
|
Related: [[2026-08-01-donut-voiced-interview-build]] (the prior slices).
|
||||||
+40
-76
@@ -46,74 +46,33 @@ upstream API key stays server-side (INV-003).
|
|||||||
|
|
||||||
_As of 2026-08-02:_
|
_As of 2026-08-02:_
|
||||||
|
|
||||||
**✅ Donut voiced-interview COMPLETE + on origin (`608e9a5`) — slices 1-3, both heid gates, KB-bridge retired to native #383.**
|
**✅ Donut voiced-interview + long-form TTS COMPLETE + PUSHED (`d59f907`).** The whole arc — auto-TTS, KB-bridge →
|
||||||
Operator ask "add auto-tts to the web gui" grew into a voiced, corpus-grounded Tier-3 interview character. Slice 1
|
native `reference_knowledge`, then this session's delivery fixes — is on origin. This session (`d59f907`, 546 green,
|
||||||
(persona), 2 (auto-TTS), 3 (KB-bridge — now RETIRED to native `reference_knowledge`); both heid gates triaged+fixed;
|
long-form live-verified 106.6s / one header):
|
||||||
P&P verification done + #382/#383 closed. Pushed through `608e9a5`.
|
- **Gibberish → English pinned** (DEC-9): `language:"en-us"` on every gateway call (the multilingual model drifted).
|
||||||
**🔨 IN-FLIGHT: TTS delivery fine-tuning — 4 commits LOCAL/unpushed (`7856ec5`→`9041f1f`), "works kinda" on Safari,
|
- **Truncation → client-side chunking** (DEC-10): Zonos hard-caps ONE synth at 6144 tok / 71.2s (infra-ops; a
|
||||||
RESIDUAL FIXES PENDING (operator: "continue fixing"). Operator HOLDING the push until Safari audio is right.**
|
delivery-INDEPENDENT 86.3Hz codec constant; `max_tokens>6144` 400s). `chunk_text` (paragraph-first, greedy ~75% of
|
||||||
See the TTS line below. Contract `docs/contracts/donut_voiced_interview.contract.md`.
|
cap for prosody, sentence→clause fallback) + `tts_stream_long` concatenate int16 PCM behind ONE WAV header. `/api/tts`
|
||||||
- **Slice 2 (TTS):** `src/ratatoskr/tts.py` (Zonos gateway client + `pad_to_dials`) + `/api/tts` proxy in `web/server.py`
|
→ **POST** (DEC-10a) so a long turn rides the body, not a length-capped URL; outer cap 2000→8000.
|
||||||
(voice map `ratatoskr:donut→donut`, serialize lock, 503 degrade) + `index.html` 🔊 toggle (opt-in, localStorage,
|
- **Persona → dialogue-only** (`docs/characters/donut.md`, live-patched to `ratatoskr:donut`): no asterisk RP beats
|
||||||
default off) / speak-on-`done` / AbortController cancel-on-new-turn / `<audio>` sink. `RATATOSKR_TTS_URL` override.
|
(they were voiced as gibberish) + ALWAYS call `reference_knowledge` before answering (prompt-level; can't force
|
||||||
LIVE: Donut voice + affect dials → 44.1kHz wav (booth `http://10.100.10.50:8090/b/donut-voiced/`). Gateway
|
tool_choice from the define surface).
|
||||||
`http://10.100.79.3:8890/v1/audio/speech`, **wav-only** (mp3/opus→mislabeled PCM), emotion_valence/arousal from live PAD.
|
- **Both heid gates triaged + fixed** (4-arm panels): untrusted /api/tts body fields degrade never-500 (huge-int PAD
|
||||||
- **Slice 3 (KB-bridge):** `src/ratatoskr/kb_bridge.py` `pin_kb_context(question, agent_id, *, client)` — THE one seam
|
OverflowError, non-str agent_id, lone surrogate, whitespace text); lock+client released on EVERY peek escape (was a
|
||||||
(INV-KB-1), allowlist-gated (`ratatoskr:donut`→"Dungeon Crawler Carl"), timeout-bounded (20s), degrades to [] on any
|
permanent deadlock); mid-stream-after-commit degrades not raises (`yielded_any` pivot); non-WAV 200 rejected (RIFF
|
||||||
fail (INV-KB-3, CancelledError propagates). `wt.stream_turn` gained a `memory_context` passthrough (defaults None —
|
sniff + bounded header scan). +14 regression tests. Contract canonical (DEC-9/10, FN chunk_text/tts_stream_long).
|
||||||
seam-review caught the contract's touch-list undercounting `wt.py`). `TurnHandle.agent_id` + browser sends agent_id.
|
|
||||||
**CONSULT FOOT-GUN:** an unconstrained Mimir consult LOOPS read_note↔search past 60s; the tuned prompt
|
Prior build detail (slices 1-3, the earlier heid gates, P&P #382, KB-bridge retirement to native #383 as v1.0.0b167)
|
||||||
"search_library EXACTLY ONCE, no read_note" converges ~3-15s. **KNOWN LIMIT (not a defect):** DCC's fiction index is
|
is on origin through `608e9a5` and in `persistent-memory.d/2026-08-01-donut-voiced-interview-build.md` + the git log.
|
||||||
weak (scores ~0.02, failed backfill — worldtree-dev item), so grounding is opportunistic; Donut's DCC training
|
|
||||||
knowledge already grounds her well (live smoke: she answered fully in-voice even when the bridge degraded to []).
|
**⚠️ NEXT SESSION — `reference_knowledge` returns EMPTY for Donut; worldtree-dev fix queued (NOT ratatoskr).**
|
||||||
- **✅ heid-bug-hunt (thread `01KZ0351KJRCN4GX8EM4349GVE`) TRIAGED + FIXED (`56dce00`, +11 tests, 543 green).**
|
Root-caused this session: DCC corpus (`fiction/b59c147c5ce0/`) was ingested BEFORE Worldtree #380 fixed wing-blind
|
||||||
4 arms/11 findings; fixed 8 (five were constructible HTTP-500s from wire input — unhashable agent_id,
|
indexing, so its notes filesystem-live in the `fiction` wing but its INDEX ROWS landed in `main`; the Tier-3
|
||||||
huge-int-pad OverflowError, non-str content crashing question.strip; plus WAVE-tag check, blob-URL leak,
|
`reference_knowledge` tool is scoped to `fiction` (NO score floor — my ~0.03 hits would rate "high"), so Donut searches
|
||||||
Mimir-session cleanup via `sessions.delete`+holder, `: keepalive` SSE frame before the KB consult, text-cap
|
an index with no DCC rows. Mimir (all-wing librarian) finds DCC fine in `main` — that diagnostic isolated it. worldtree-
|
||||||
413 + 60s timeout). Refuted the 3-arm "memory_context unverifiable" alarm (tests + live SDK). Accepted (trust
|
dev RULED **re-ingest DCC into fiction** (rejected the tier3_wings→main widen; my containment argument held): muninn
|
||||||
model): caller-supplied agent_id (LAN/no-auth debug tool). All 5 adversarial inputs live-smoked → 200/413/400.
|
re-ingest `wing=fiction` → the #381 restart-after-ingest → **worldtree-dev PINGS me → I drive a canonical-term Donut
|
||||||
- **✅ heid-code-review (thread `01KZ0324M02E90D3K2Q91JAH0J`) TRIAGED + FIXED (`eb0767e`, 545 green).**
|
turn to confirm hits** (offer standing, thread `01KZ208P…`). Donut degrades in-voice gracefully until then.
|
||||||
3 arms (Kimi transport-stalled); reconciled against 56dce00 — 3 findings already closed by the bug-hunt
|
|
||||||
(the two firewalled lenses converged independently on the same 3 defects). Fixed: **F7 no-hit sentinel** (the
|
|
||||||
sharpest — Mimir emits NO_CORPUS_MATCH on no-hit → pin_kb_context drops it, so a "no results" answer is never
|
|
||||||
pinned as Donut's memory; live-proven grounding 5.6s / no-match 0.7s→[]) + contract precision (DEC-8 stale:
|
|
||||||
donut voice registered early, live gateway read INVERTED the 3-arm "revert to preset" remedy; FN url param,
|
|
||||||
gateway-enforced voice, browser-sent PAD) + 4 test-gaps (read_note-distinguishing, literal bound, route roster
|
|
||||||
+/api/tts+/messages, KB-seam-degrades-but-turn-survives). Accepted: caller-agent_id (trust model), no DEC-5
|
|
||||||
concurrency test (asyncio.Lock trivially correct). **BOTH HEID GATES NOW COMPLETE.** HEAD `eb0767e`.
|
|
||||||
- **✅ P&P verification DONE — #382 CLOSED both sides.** Re-ran the P&P-dismiss shape 3× on :8081/b166 (intermittency
|
|
||||||
test) → 3/3 grounded, zero discard-and-substitute (note-extracted citations, not raw Austen); reported to infra-ops
|
|
||||||
(`01KZ0HG9G7...`); worldtree-dev credited the 3-session methodology + downgraded the failed-DCC-backfill to
|
|
||||||
correctness-polish. **Prior design → `persistent-memory.d/2026-08-01-donut-voiced-interview-build.md`.**
|
|
||||||
- **✅ KB-BRIDGE RETIRED (`09e4257`) — WT #383 native Tier-3 `reference_knowledge` DEPLOYED as v1.0.0b167.**
|
|
||||||
Operator greenlit the #383 deploy (relayed `01KZ0HPT6J...`); worldtree-dev deployed to :8081+demo, validated
|
|
||||||
`builtin_tools=['reference_knowledge']` on both, pinged live (`01KZ0HTJ5M...`). LIVE-VERIFIED before deletion:
|
|
||||||
Donut called the native tool + grounded in DCC Collapse content in-voice (degrades gracefully on absent content).
|
|
||||||
Deleted `kb_bridge.py` + `test_kb_bridge.py` + the one `server.py` call-site + the SSE keepalive + the bridge-only
|
|
||||||
agent_id plumbing (TurnHandle.agent_id, submit read, index.html turn-body). KEPT `wt.stream_turn`'s memory_context
|
|
||||||
param (inert SDK-parity) + the non-str-content 400 guard. Contract marks slice-3 RETIRED (historical record kept).
|
|
||||||
#382/#383 both closed. **Native tool is strictly better than the bridge** (in-turn, provenance packets, server-side
|
|
||||||
grounding rule, fail-soft, no separate consult). FOOT-GUN (#381): freshly-ingested content needs the
|
|
||||||
restart-after-ingest runbook to be Tier-3-recallable.
|
|
||||||
- **🔨 TTS delivery — STREAMING via Web Audio; "WORKS KINDA" on Safari, RESIDUAL FIXES PENDING (operator: "continue fixing").**
|
|
||||||
**4 commits LOCAL/unpushed.** Arc: buffered (`6c3c08b`, superseded) → streaming play-as-it-arrives (`7856ec5`) →
|
|
||||||
hardening (`677b033`: no-store page + first-interaction unlock + error-name ticker) → **Web Audio (`9041f1f`)**.
|
|
||||||
- **Server:** gateway ALREADY streams (chunked int16 WAV, TTFB ~0.44s, placeholder `0xFFFFFFFF` sizes) — the
|
|
||||||
buffering was OUR proxy; **DON'T rewrite the header** (that forces buffering). `tts.py:tts_stream` (async-gen,
|
|
||||||
pass-through) + `gateway_body`; `/api/tts` is **GET** → chunked `StreamingResponse` (peek-first-chunk → 503 on
|
|
||||||
bad open; serialize lock; PAD via `p`/`a` query floats; text capped 2000 for the URL, `_TTS_MAX_TEXT_CHARS`).
|
|
||||||
Page served **no-store** (kills stale-cache confusion — a recurring foot-gun through this debugging).
|
|
||||||
- **Playback is WEB AUDIO, not `<audio src>`:** Safari REFUSES a streaming `0xFFFFFFFF`-length WAV via `<audio src>`
|
|
||||||
(`NotSupportedError`). `index.html:speakOnDone` fetches the chunked stream, skips the WAV header to the data chunk,
|
|
||||||
decodes int16 LE PCM → Float32 → schedules GAPLESSLY into an `AudioContext` (BufferSource per chunk). Validated in
|
|
||||||
Chromium (Playwright): 43 nodes, 5.1s decoded, no error. **Couldn't test headless WebKit — missing system libs
|
|
||||||
(libwoff2 etc.); an infra-ops `playwright install-deps webkit` install would enable it.** webkit downloaded to
|
|
||||||
`~/.cache/pw-local` already.
|
|
||||||
- **Autoplay:** AudioContext starts suspended; `_unlockTtsAudio()` resumes it on FIRST interaction anywhere +
|
|
||||||
toggle/submit (Safari+Chrome need resume from a gesture). Ticker names the DOMException on failure.
|
|
||||||
- **⏭ NEXT SESSION: diagnose the "works kinda" residual on real Safari** (candidates: chunk-boundary clicks/gaps from
|
|
||||||
per-BufferSource scheduling; TTFA/latency; a scheduling-drift underrun; affect-dial quality — operator will specify
|
|
||||||
the symptom). Fix, verify, THEN push the 4 commits. `:8765` runs the current (Web Audio) build.
|
|
||||||
|
|
||||||
**✅ SHIPPED + PUSHED since v0.22.0 (origin at `14bbc2b`):** the worldtree-sdk cutover (#20, **v0.22.0**, 7 slices,
|
**✅ SHIPPED + PUSHED since v0.22.0 (origin at `14bbc2b`):** the worldtree-sdk cutover (#20, **v0.22.0**, 7 slices,
|
||||||
494 green — the big one) + **bifrost 1.1.5** (`3ef3a5e`, **v0.22.1**) + **worldtree-sdk 1.0.0→1.1.1→1.1.2**
|
494 green — the big one) + **bifrost 1.1.5** (`3ef3a5e`, **v0.22.1**) + **worldtree-sdk 1.0.0→1.1.1→1.1.2**
|
||||||
@@ -176,14 +135,13 @@ Full record → `persistent-memory.d/2026-07-18-368-silo-test-passed.md`. Siblin
|
|||||||
(2) R39 Phase-2 **matched-quartets rebuild** (confirmatory, "whenever"); (3) bifrost **snapshot-cursor
|
(2) R39 Phase-2 **matched-quartets rebuild** (confirmatory, "whenever"); (3) bifrost **snapshot-cursor
|
||||||
adoption** (ruled normative, not blocking → `persistent-memory.d/2026-07-16-bifrost-cursor-conformance.md`).
|
adoption** (ruled normative, not blocking → `persistent-memory.d/2026-07-16-bifrost-cursor-conformance.md`).
|
||||||
|
|
||||||
**Substrate / environment:** branch `main` at **v0.22.0** — slices 1-5 (`b1fbadd`→`4e20030`, v0.21.3–.18)
|
**Substrate / environment:** branch `main`, **HEAD `d59f907` PUSHED to origin** (v0.22.0 cutover + bifrost 1.1.5
|
||||||
PUSHED to origin; **slice-6 arc `de9a5ba`→`11ae2f0` (v0.21.19–.20) AND slice-7 `ec68b1f` (v0.22.0) + this
|
v0.22.1 + this session's TTS work all on origin; nothing local-only but the dirty `graphify-out/`). origin
|
||||||
snapshot are LOCAL — NOT yet pushed** (operator's call). origin
|
`git@gitea.phasefinal.com:vh/ratatoskr.git`. **Core dep: `worldtree-sdk==1.0.0`** (gitea PyPI, `[tool.uv.sources]`;
|
||||||
`git@gitea.phasefinal.com:vh/ratatoskr.git`. **Core dep:
|
`httpx-sse` removed — SDK owns SSE). **worldtree-sdk 1.2.0 is AVAILABLE (repin DEFERRED to a dep pass, my rec) —**
|
||||||
`worldtree-sdk==1.0.0`** (gitea PyPI, `[tool.uv.sources]`; **`httpx-sse` REMOVED at slice-7** — SDK owns SSE). bifrost
|
new `ResponseTooLarge` (a `ProtocolError`, NOT caught by our `except ConnectFailed`) + response-alloc caps that assume
|
||||||
**`==1.1.4`** / wire v0.7; WT openapi vendored 2.3.0, **conversation-api-spec re-synced to v1.1** (`b4a278c`);
|
a 2.5.0 server (worldtree-dev runs it, so safe); wtsdk-dev announce `01KZ1ZYM…`. bifrost **`==1.1.5`** / wire v0.7; WT
|
||||||
**suite 494 green** (slice-6 added the admin adapter tests + heid fixup tests, ~offset by the retired
|
openapi vendored 2.3.0, conversation-api-spec v1.1; **suite 546 green.** Personal WT on **b128**
|
||||||
hand-rolled admin tests + the whole `test_sse_client.py`). Personal WT on **b128**
|
|
||||||
(`http://10.250.50.152:8081`; #368 silo + #364 promotion-hygiene live both instances). The combined
|
(`http://10.250.50.152:8081`; #368 silo + #364 promotion-hygiene live both instances). The combined
|
||||||
**:8392** provider (memory+affect) + **:8765** web are THE surfaces, dev-box BACKGROUND SHELLS —
|
**:8392** provider (memory+affect) + **:8765** web are THE surfaces, dev-box BACKGROUND SHELLS —
|
||||||
restart via `scratchpad/relaunch_by_pid.py <pid>` (pid via `ss -ltnp | grep <port>`). `env.sh` sets
|
restart via `scratchpad/relaunch_by_pid.py <pid>` (pid via `ss -ltnp | grep <port>`). `env.sh` sets
|
||||||
@@ -351,6 +309,10 @@ decision. Captures rationale that won't be obvious from code alone.
|
|||||||
- `[2026-07-30]` **Versioning cadence → RELEASE-ONLY (operator-ratified, brokkr-smithy relayed).** Retired per-commit bump+tag; tag only releases; between releases `feat:`/`fix:` SHAs. Existing ~112 tags left as-is. Global CLAUDE.md SemVer being amended to match.
|
- `[2026-07-30]` **Versioning cadence → RELEASE-ONLY (operator-ratified, brokkr-smithy relayed).** Retired per-commit bump+tag; tag only releases; between releases `feat:`/`fix:` SHAs. Existing ~112 tags left as-is. Global CLAUDE.md SemVer being amended to match.
|
||||||
- `[2026-08-01]` **bifrost 1.1.4→1.1.5 (v0.22.1, `3ef3a5e`, pushed)** — optional-store-verb 500→`unsupported_capability` hardening; provider restarted onto it.
|
- `[2026-08-01]` **bifrost 1.1.4→1.1.5 (v0.22.1, `3ef3a5e`, pushed)** — optional-store-verb 500→`unsupported_capability` hardening; provider restarted onto it.
|
||||||
- `[2026-08-01]` **Sindra saga — restored from local-index burial, wiped, smoke-tested.** The v0.22.0 web restart dropped her live session AND the schema-v2 discard buried her from the picker; migrated her v1→v2 from authoritative WT (real role `thoughtful-character`, not the stale `mistral-small-4`), then `scripts/reset-sindra-stores.sh` wiped memory+persona for a from-scratch smoke.
|
- `[2026-08-01]` **Sindra saga — restored from local-index burial, wiped, smoke-tested.** The v0.22.0 web restart dropped her live session AND the schema-v2 discard buried her from the picker; migrated her v1→v2 from authoritative WT (real role `thoughtful-character`, not the stale `mistral-small-4`), then `scripts/reset-sindra-stores.sh` wiped memory+persona for a from-scratch smoke.
|
||||||
|
- `[2026-08-02]` **Donut TTS: English pin + long-form chunking + POST + dialogue-only persona + both heid gates — shipped `d59f907` (pushed).** Gibberish→`language:"en-us"`; truncation→client-side chunk+concatenate under the 71.2s/6144-tok cap; persona dialogue-only + always-call `reference_knowledge`; 4-arm gates fixed a lock deadlock + several untrusted-input 500s the GET→POST switch re-opened. → `persistent-memory.d/2026-08-02-donut-tts-chunking-english-gates.md`
|
||||||
|
- `[2026-08-02]` **`reference_knowledge` empty-recall root-caused to a Worldtree WING-MISFILE; worldtree-dev ruled re-ingest DCC into `fiction` — EXECUTION DEFERRED to NEXT SESSION.** DCC index rows landed in `main` (pre-#380 wing-blind ingest) while the Tier-3 tool is scoped to `fiction`; NOT ratatoskr code. Ruling rejected the tier3_wings→main widen (my containment argument held). Tracked: worldtree-dev thread `01KZ208P…` (they ping when DCC lands in fiction); my post-fix canonical-term verify offer stands. See Current state § NEXT SESSION.
|
||||||
|
- `[2026-08-02]` **worldtree-sdk 1.2.0 repin DEFERRED to a dep pass (my rec; operator to decide).** New `ResponseTooLarge` (a `ProtocolError`, NOT caught by our `except ConnectFailed`) + response-alloc caps that assume a 2.5.0 server (worldtree-dev runs it → safe in practice). When repinning, add `ResponseTooLarge` to the caught envelopes. Tracked: wtsdk-dev announce thread `01KZ1ZYM…`.
|
||||||
|
- `[2026-08-02]` **Filed issue #21** (sibling POST handlers `_create_session`/`_submit_turn` 500 on malformed JSON — the parse-JSON-or-400 asymmetry the heid gates flagged; pre-existing, out of the TTS diff's scope). Fix = a shared parse-JSON-or-400 helper.
|
||||||
|
|
||||||
_67 older entries (2026-05-* debug-TUI/web era + the 2026-06-14 → 06-18 Bifrost-provider build / #17+#18 / #295-296 era) archived to archival-memory.md._
|
_67 older entries (2026-05-* debug-TUI/web era + the 2026-06-14 → 06-18 Bifrost-provider build / #17+#18 / #295-296 era) archived to archival-memory.md._
|
||||||
|
|
||||||
@@ -398,5 +360,7 @@ defense against re-attempting the same cul-de-sac.
|
|||||||
|
|
||||||
- `[2026-08-01]` **`local_agents` index schema v1→v2 bump SILENTLY buries pre-cutover consumer agents from the picker** — `load_local_agents` returns `[]` on version mismatch (no migration path); the v0.22.0 restart made Sindra vanish even though she was alive on WT. Fix applied ad-hoc: migrate the v1 row → v2 from authoritative WT data (the v1 `model` field held a stale model name, NOT the current role). A one-time v1→v2 migration guard is the durable fix (unbuilt; operator-flagged).
|
- `[2026-08-01]` **`local_agents` index schema v1→v2 bump SILENTLY buries pre-cutover consumer agents from the picker** — `load_local_agents` returns `[]` on version mismatch (no migration path); the v0.22.0 restart made Sindra vanish even though she was alive on WT. Fix applied ad-hoc: migrate the v1 row → v2 from authoritative WT data (the v1 `model` field held a stale model name, NOT the current role). A one-time v1→v2 migration guard is the durable fix (unbuilt; operator-flagged).
|
||||||
- `[2026-08-01]` **Zonos: mp3/opus `response_format` silently return mislabeled PCM** (no encoder wired) — use `response_format:"wav"` only. And use the GATEWAY :8890, NOT the engine :1920 (rep-penalty bug pads ~70s silence + ignores voice).
|
- `[2026-08-01]` **Zonos: mp3/opus `response_format` silently return mislabeled PCM** (no encoder wired) — use `response_format:"wav"` only. And use the GATEWAY :8890, NOT the engine :1920 (rep-penalty bug pads ~70s silence + ignores voice).
|
||||||
|
- `[2026-08-02]` **Zonos hard-caps ONE synthesis at `max_tokens=6144` = 71.2s of audio** (6144 / 86.3Hz codec frame rate; `>6144` → HTTP 400, an architectural sequence limit). 86.3Hz is a **delivery-INDEPENDENT constant** — 6144 tokens is ALWAYS 71.2s regardless of emotion/rate (emotion changes words-per-71.2s, not seconds-per-token). Any turn longer than ~71s REQUIRES client-side chunk-and-concatenate (raw PCM, ONE WAV header — never stitch multiple WAV headers). Fixed in `d59f907` (DEC-10). Don't chase a "raise max_tokens" fix — the gateway rejects it.
|
||||||
|
- `[2026-08-02]` **A GET→POST endpoint switch re-opens untrusted-TYPE crashes that string-only query params silently masked.** Under GET, `p`/`a`/`agent_id` were always `str|None`; under a JSON POST body they can be a huge int (`float()`→OverflowError), an unhashable list/dict (`dict.get`→TypeError), or a lone surrogate (utf-8 encode→UnicodeEncodeError) — each a 500 the old code never saw. Guard EVERY body field when moving a query endpoint to a JSON body. Both heid gates converged on these (all 4 arms). Fixed in `d59f907`.
|
||||||
|
|
||||||
_34 older entries (2026-05-* debug-TUI/web era + the 2026-06-14 → 06-18 foot-gun cluster) archived to archival-memory.md._
|
_34 older entries (2026-05-* debug-TUI/web era + the 2026-06-14 → 06-18 foot-gun cluster) archived to archival-memory.md._
|
||||||
|
|||||||
Reference in New Issue
Block a user