B.D. Murphy 9dfa7915ee Probe suite: T06/T07 now test, T08 names its real blocker
The dry run passes since routes_compute.py:1792 was aligned with read_bundle
(separators + ensure_ascii=False), so three tests had to catch up. All three
carried narratives written when the bundle was rejected, and each kept asserting
a reason that had stopped being true — a BLOCKED test is a finding, so a stale
BLOCKED reason is a finding about the wrong world.

T06 re-runs the dry run and compares responses, proving validation is
deterministic. It says plainly that re-import suppressing stored rows is NOT
covered: that path needs rows that persist, and the import still builds
InMemoryAudioImportStore.

T07 reconciles the controller's counts against the bytes sent. 8884 records in,
8883 accounted for, plus the book record it does not count — so a controller
that silently dropped a record kind now fails here instead of passing quietly.

T08 keeps BLOCKED, but for the reason that is actually true: no Postgres
AudioImportStore adapter exists, so even a successful commit would return a
uuid4 project_id while translation_utterances stayed empty. Its text names
InMemoryAudioImportStore on purpose, so wiring an adapter fails a test and
forces the verdict to be re-decided.

Suite: 9 PASS / 0 FAIL / 1 BLOCKED (T08). Tests 30 -> 40.
2026-10-16 00:27:24 -07:00

UmbraAudio

Quality-first multi-pass audiobook generation from English manuscripts.

Features

  • 5-pass pipeline: Analysis → Voice Design → Mapping → Test → Generate
  • Multi-engine TTS: Chatterbox (primary), Qwen3-TTS (secondary)
  • LLM-enhanced: BookNLP for NLP, LLM for profiling/emotion/pronunciation
  • Web review: FastAPI + HTMX at checkpoints for human approval

Quick Start

python -m umbraaudio.cli init <manuscript.epub> --name 'My Book'
python -m umbraaudio.cli analyze
python -m umbraaudio.cli voices
python -m umbraaudio.cli review

Requirements

  • Python 3.11+
  • NVIDIA GPU with CUDA support (RTX 3060 or better recommended)
  • ffmpeg

Development

pip install -e ".[dev]"
ruff check umbraaudio/
pytest tests/ -v

Commit cadence: commit at least once every Sunday. Never leave a week (let alone a month) of work uncommitted — a single accidental git checkout on 2026-09-20 wiped out a month of changes to umbraaudio/web/routes.py. See AGENTS.md → Commit Cadence.

scripts/commit_check.sh enforces the nudge: it exits non-zero once the tree has been dirty longer than a week. The LaunchAgent com.umbraaudio.commitcheck runs it every Sunday at 18:00 and posts a macOS notification when there is uncommitted work.

scripts/commit_check.sh            # warn if dirty > 7 days
scripts/commit_check.sh --days 3   # tighter threshold
scripts/commit_check.sh --any      # warn on any uncommitted change

Rebuilding from source

The repo tracks source only; large runtime data is reconstructed as needed.

  1. Models: weights are not committed (see .gitignore). Download them:

    bash scripts/download_models.sh   # ~9 GB, targets ./models
    
  2. Qwen3-TTS is a git submodule pinned to upstream commit 022e286:

    git submodule update --init --recursive
    

    The tts_server/web-demo backend includes a local UI customization to qwen_tts/cli/demo.py. It is preserved as a patch — reapply it after checking out the submodule:

    cd Qwen3-TTS && git apply ../scripts/qwen3_tts_demo_umbra_patch.patch
    
  3. Environment: copy/keep .env (contains secrets) and set UMBRA_TTS__* model paths under models/.

Book projects (e.g. DealHunterShip_...) are committed separately under their own project directories and are not part of this program repository.

Description
Quality-first multi-pass audiobook generation pipeline (5-pass: Analysis -> Voice Design -> Mapping -> Test -> Generate). FastAPI+HTMX review UI, Edge-TTS/Qwen3-TTS multi-engine voice, SQLite state.
Readme Apache-2.0 37 MiB
Languages
Python 84.8%
HTML 11.4%
Shell 3%
PLpgSQL 0.7%