May 10, 2026
Voice collapses onto one dependency, dead code keeps dying
Chalie's TTS and STT stack merges onto a single package while a sweeping cleanup pass strips hundreds of lines of zero-caller code.
Today was about collapsing complexity, not adding it. Voice had been running on two separate libraries doing overlapping jobs — kokoro-onnx for speech synthesis, espeak-ng for phonemization — glued together with hand-rolled patches. That’s exactly the setup my own conventions warn against: when a third-party library misbehaves, the fix is to read its public API properly, not build a wrapper around its internals. So the whole stack moved onto a single package, moonshine_voice, which owns G2P, ONNX inference, and voice asset downloads for both text-to-speech and speech-to-text. Net effect: kokoro-onnx and espeak-ng are gone, voice.py loses 114 lines, and the day’s diff is -94 LOC across five files with the full unit suite green.
That collapse surfaced two real bugs. Moonshine’s neural G2P strips punctuation before it reaches the synthesizer, so a multi-sentence reply came out as a flat, run-on read with no natural pauses. The fix segments text on real sentence and clause boundaries, synthesizes each piece independently, and stitches the audio back together with silence pads sized to the punctuation mark — a period gets a longer pause than a comma. Then a type bug: the new synthesize() call returns a plain Python list instead of a NumPy array, so every multi-segment concatenation crashed with 'list' object has no attribute 'dtype'. One np.asarray fixed it, and the silence padding was pinned to float32 to match. A same-day follow-up tuned the pause durations down (chunky at first pass) and taught the preprocessor to letter-space short ALL-CAPS acronyms like “MB” and “VM” — Moonshine’s G2P was reading them as fake words instead of spelling them out.
Underneath the voice work, a broader effort kept chipping at dead surface area — the same “smaller is safer” discipline running for days. Fifteen Redis-compatibility methods came out of MemoryStore, a class that’s been in-process only since the Redis rip and was still carrying zset/hash/list helpers nobody called. The output-queue subsystem was ripped entirely — enqueue/dequeue/delete had zero live callers since the reasoning-loop refactor, so out it went with its config key and diagnostic endpoint. Smaller drops followed the same pattern: an unused ONNX multi-label predictor, ability lifecycle hooks with zero overrides anywhere in the codebase, a dead vault password-change method, an unused list-prompt helper, and boot-time service registrations for services already removed weeks earlier but still logging harmless “module not found” warnings on every cold start.
One functional regression got caught and reverted: a schedule-search delegation inside memory recall had been erroneously removed. It’s the only path that surfaces scheduled items after a transcript reset — without it, the model has no way to know a reminder exists unless the user names it directly. Testing had already caught the regression (a key test dropped from 0.987 to 0.68), exactly the signal that should stop a bad change before it ships. Restoring the delegation put the score back.
A few smaller fixes rounded out the day: werkzeug’s per-request INFO logging was silenced (the frontend polls health and scheduler endpoints every 30-60 seconds; none of that traffic needs a log line), the voice health endpoint now returns 200 instead of 503 for the expected “dependencies missing” state so the UI can read the actionable hint instead of silently giving up, a theme-aware label fix for a UI pill invisible in light mode, and text documents now get their clean_text field populated on ingest.
None of this is flashy, and that’s the point — a founder shipping every day means most days look like this: collapse a dependency, kill a hundred lines nobody was calling, catch a regression before it compounds. The voice pipeline is simpler and more correct than it was yesterday, and the codebase has less to reason about tomorrow.
-
Collapsed voice onto moonshine_voice, dropping kokoro-onnx and espeak-ng (-94 LOC net)
-
Fixed prosody: punctuation-driven segmentation with silence pads, halved pause durations, ALL-CAPS acronym expansion
-
Fixed a list-vs-ndarray type bug crashing multi-segment TTS concatenation
-
Restored schedule search delegation in memory recall after a caught regression (0.987 to 0.68 to fixed)
-
Removed 15 dead MemoryStore methods, the output-queue subsystem, and several other zero-caller code paths