fix(frank-tts): make the boot warm pass survive both readers of its env
`WARM_TEXT` reaches the container **with its quotes**. The unit reads the env file through podman's `--env-file`, which takes the literal remainder of the line — no shell parsing — while bash `source` strips one layer. The hook interpolated the raw value into the synthesis body, so with the quotes intact the JSON was invalid and every voice logged "registered, but the warm synthesis failed" while a hand-run hook (bash shape) succeeded. Reproduced both ways against a real `podman run --env-file`, not by reading the man page. The hook now strips exactly one matched pair — only when both ends are the same quote AND the inner content carries another quote or a backslash, so a value that legitimately contains quotes is never mangled — and then JSON-escapes what is left, which is what makes a sentence like `He said "hi\" once"` arrive as itself instead of corrupting the body. The seam gains a test that reads `scripts/frank-tts-engine.env` BOTH ways — `source` and the way `podman --env-file` does — and asserts the engine receives the same sentence either way, in both shapes. A test that only sources the file cannot see this bug, which is how it survived the first deploy.
This commit is contained in:
@@ -126,8 +126,20 @@ HEALTH_WAIT=300
|
||||
# second (warm-timing) pass repeats. Fixed on purpose: the cold=/warm= numbers in
|
||||
# the journal are comparable across boots only if the input is the same. Kept
|
||||
# short because warming a library is serial — one cold decode per voice, 6-8 s
|
||||
# each, inside the unit's start deadline. Quoted because podman's env-file parser
|
||||
# and a shell `source` must both read the sentence as ONE value.
|
||||
# each, inside the unit's start deadline.
|
||||
# QUOTED, and the quoting means two different things to the two readers of this
|
||||
# file, which is the trap here:
|
||||
# * bash (`set -a; source`, how the repo's seams and any human read it) needs
|
||||
# the quotes — an unquoted value with spaces is word-split and the second
|
||||
# word is executed as a command.
|
||||
# * podman's `--env-file` (how the unit actually reads it) does NOT strip
|
||||
# quotes: measured 2026-10-18 against the image's pinned base, the value
|
||||
# arrives as `"Warm up, one two three."` WITH them. Interpolated into the
|
||||
# hook's JSON body that is `""Warm up…""`, the engine's parser rejects it,
|
||||
# every voice stays cold and the boot still looks healthy.
|
||||
# So the value stays quoted for bash and the hook strips one matched pair before
|
||||
# it builds the request, then escapes what is left. Both readers now agree, and a
|
||||
# sentence containing a quote or a backslash still arrives verbatim.
|
||||
WARM_TEXT="Warm up, one two three."
|
||||
|
||||
# Per-request ceiling for the hook. A cold voice measures 6-8 s, so 120 s is
|
||||
|
||||
Reference in New Issue
Block a user