From 6bf0baa2f86e1c69bf7d992bff7243ffb3a85817 Mon Sep 17 00:00:00 2001 From: Umbra Tools Date: Fri, 6 Nov 2026 20:09:23 -0800 Subject: [PATCH] Record the Chinese-only pipeline finding and the delivery script gate The "Spanish" production on oldbox is a second Chinese draft, and the drafter's hard-coded Simplified Chinese instructions are why. Also recorded: the target-language audio render belongs to UmbraTrans per spec 18, the Qwen3-TTS cross-language clone probe is still outstanding, and the live UI was re-measured after the gate. --- AGENTS.md | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 02ab49c..5893e75 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -290,11 +290,55 @@ Each pass has quality gates. Quality is the primary concern; generation speed is - **UmbraAudio suite: 890 passed / 8 failed / 6 skipped** - the same 8 pre-existing failures (2 `test_pronunciation`, 6 `voice_profile_manager` accent); +9 new tests, no regressions. Web server restarted; all pages return 200 (auth gate intact, `/` -> 303 `/login`). +- **The pipeline is CHINESE-ONLY, and one production says otherwise.** Measured on oldbox + (2026-11-06): `productions/deal-hunter-es` declares `target_language: es-ES`, its glossary + says `"script": "Spanish"` with Spanish style rules and the title `Cazador de Ofertas`, and + it has a complete 32-chapter run (39,083 s) - **but all 3,038 translated paragraphs are + Chinese** (3,034 with Han characters, same proportion as the zh run; 2,792 of 3,038 differ + in wording from zh, so it is a *second Chinese draft*, not a copy). **Cause: the drafter's + instructions are hard-coded to Simplified Chinese in three places** - + `prompts.py` `SYSTEM_DRAFTER` ("把英文太空冒险小说译成简体中文"), `draft_prompt` + ("请把下面英文译为简体中文", JSON key `"zh"`), `SYSTEM_CRITIC` ("对照英文原文和中文译文"). + The glossary carries the target but the *instruction* says Chinese, so the model followed + the instruction; the critic is hard-coded the same way, so it checked the Chinese text and + found nothing wrong - there was nothing wrong with it for the language it was asked about. + `pipeline.py` has **zero** references to `target_language`. **Consequence: no non-Chinese + translation has ever been produced by that pipeline**; the other 9 languages exist only as + the single-pass sample files. +- **That defect is now guarded at the contract boundary** (commit `3db6ac3`). + `umbraaudio/languages.py` gained script expectations per language (`Language.scripts`, + `required_script`, `forbidden_scripts`) plus `script_counts()` and `script_mismatch()`; + `import_translations` now checks the delivered text's script against the declared language + **before writing a single row** and refuses the delivery. Japanese needs kana, Korean needs + Hangul, and Chinese carrying kana is a Japanese translation in the wrong lane. An unknown + language is not checked (no expectation to check against). Proven on the real data: the es + delivery is refused with *"the text is mostly Han characters, so it is not Spanish"* and + **0 rows written**; the 4,300-row Chinese delivery still imports unchanged. + The check is about the *script*, not the language - it cannot tell Spanish from Portuguese, + but it can tell Chinese from Spanish, which is the mistake that actually happens. +- **Target-language audio is not built here, and that is deliberate.** Measured: + `umbraaudio/generation/chapter_builder.py` synthesizes `u["text"]` (the English source) and + **never reads `utterance_translations`** - the translation does not reach the TTS path at + all. Spec 18 §4.1 assigns "target-language voice casting" and "target-language TTS + rendering" to **UmbraTrans**, and §4.2 forbids UmbraTrans from reusing UmbraAudio's audio + markers as target-language markers. So the renderer belongs to UmbraTrans, not here. The + alignment pass is what makes it possible: it hands UmbraTrans one row per utterance, keyed + to the verified speaker, with `voiced=false` for the collapses. +- **Open prerequisite for any target-language render:** does Qwen3-TTS speak Chinese with an + **English** voice reference? The engine and the server both accept a per-request + `language` (`QwenTTSEngine.generate(..., language=...)` -> `scripts/qwen_tts_server.py` + `Form("english")`), so it is possible in principle - but it has not been probed, because + LM Studio and the TTS model must not be co-resident on this 16 GB Mac and the alignment run + is using LM Studio. Probe after the alignment finishes. - **IN FLIGHT:** full-book model alignment running (`--chapters all`, output - `zhprod/delivery-full-llm.json`); progress at ch-9 of 32, **0 needing review** so far, 184 + `zhprod/delivery-full-llm.json`); progress at ch-11 of 32, **0 needing review** so far, 289 align cache entries. Auto-ingest watcher armed (`ingest-after-align.sh` waits for the process to exit, then runs `scripts/import_translations.py --write --replace` so the model-aligned delivery replaces the mechanical rows automatically). +- **Live UI re-measured after the gate commit and a server restart:** ch1 zh = 12 x "✓ + Chinese" / 354 CJK / 0 untranslated; ch6 zh = 415 x "✓ Chinese" / 8,231 CJK / 1 + untranslated (the chapter announcement); ch6 es = 0 (the Spanish lane is correctly empty - + the gate stopped the mislabelled delivery); ch6 ru = 0. - **Two production translation defects found, NOT fixed** (translation-quality, not code): `ch-15-p0100` source is a passage about dust on a console but the Chinese is "是控制台上的"; `ch-25-p0089` source describes cuboid shapes but the Chinese is "怎么才能接通电源?". Both