# talk v10 deploy — Grima ears + barge-in (2026-09-15) Operator-instructed, relayed by tts-dev. First consumer of the Parakeet/`ext-stt` seat stood up the same night — `talk` can now listen as well as speak. ## Why infra-ops and not tts-dev `/opt/docker/compose` on **nh3-dev** is `root:docker 2775` and tts-dev's project identity is not in the `docker` group — the one box of five where the deploy path is not project-writable. That is the *only* reason the deploy was relayed. ⚠ **Open question raised with the operator:** the durable fix is a group membership, not a standing relay. Every `talk` deploy currently routes through infra-ops for a permissions reason rather than a judgement one. ## Relay authorization — why this was OK to act on `feedback_no_relayed_authorization_for_irreversible_work` says a peer relaying "Vuong approved it" is **not** authorization for a no-undo action, but reversible work is fine to relay. This qualified: one-line rollback (`TALK_TAG=v10`→`v9`), `local/talk:v1..v9` all retained on the box, and both `compose.yaml` and `.env` backed up before the edit. **Checked the escape hatch existed rather than believing the message that described it.** ## What shipped repo ~/development/tts-stack @ 82f71d1, stacks/talk/ image local/talk:v10 (143 MB) live container `talk`, 0.0.0.0:8092 -> 8443, https://talk.nh3.phasefinal.com:8092/ New: `POST /api/listen` (raw-body WAV → `{"text":…}`, proxied to `ext-stt` through LiteLLM — raw body rather than multipart because `python-multipart` is not in the image), a push-to-talk mic (16 kHz mono, decimated 3:1 in an AudioWorklet), and barge-in. `compose.yaml` gained two **defaulted** env lines so the STT seat can move without a rebuild: `TALK_STT_MODEL` (`ext-stt`) and `TALK_STT_MAX_BYTES` (10 MiB ≈ 5.2 min). ## Gate — 5/5, and the discipline that matters Built → throwaway on **:8799** (never the live port) → gate → tear down → **then** cut over, in separate invocations. tts-dev's own warning: do not chain the cutover into the same invocation as its acceptance run. ✓ /api/system ✓ /api/voices 21 (predicted 21) ✓ /api/models 23 (predicted 23) ✓ /api/listen byte-exact vs ground truth ⭐ **Re-ran all four against PRODUCTION after the cutover.** A gate that only ever ran against the throwaway proves the image, not the deployment. Both new env vars confirmed *inside the running container*, not just in the file. ## ⭐⭐ The fifth gate — check the artifact AS SERVED, not as stored tts-dev's worst bug this cycle: `PAGE` is a Python string, so Python's escape handling runs over the JavaScript before a browser sees it. A JS `'didn\'t'` is valid in the file and arrives as `'didn't'` — closing the string and killing the **entire inline script**. The page still rendered; it just did nothing. `import app` passed. `node --check` on the source file passed. **Both passed because the file still holds the backslash.** So I added: fetch the page over HTTP, extract inline `