Skip to content

chore: qwen3tts standalone → hal0-slot migration prep (runbook + guarded script)#974

Merged
thinmintdev merged 3 commits into
mainfrom
chore/qwen3tts-migration-prep
Jun 29, 2026
Merged

chore: qwen3tts standalone → hal0-slot migration prep (runbook + guarded script)#974
thinmintdev merged 3 commits into
mainfrom
chore/qwen3tts-migration-prep

Conversation

@thinmintdev

Copy link
Copy Markdown
Contributor

Summary

This PR is prep-only. It does not change any running code, does not touch
the live hal0-qwen3tts.service, and makes zero live state changes. It
delivers the documentation and tooling needed to safely retire the standalone
TTS service once the hal0-native qwen3tts slot (from PR #972 + follow-ups) is
deployed and verified on CT105.

  • handoffs/qwen3tts-standalone-to-slot-migration-2026-06-28.md — migration
    runbook: preconditions, port-collision analysis, Hermes bridge repoint
    details, step-by-step cutover, and rollback.
  • scripts/migrate-qwen3tts-to-slot.sh — idempotent, guarded migration
    script (bash -n validated, NOT executed).

Guard / dry-run design

The script defaults to --dry-run and refuses to act without an explicit
--apply flag. Before any state change, three guards must pass:

  1. hal0-slot@qwen3tts state == "ready" (via /api/slots/qwen3tts)
  2. /v1/audio/speech via the hal0 front door returns a non-empty WAV
  3. Kokoro fallback slot is healthy on :8084

All edits to /var/lib/hal0/.hermes/ are done as the hal0 user (never
root) to avoid flipping ownership and taking the Hermes gateway offline.

Port-collision decision

Both the standalone service and the slot TOML default to port 8095. They
cannot coexist on that port. The script stops the standalone first, then
the hal0 slot manager takes over 8095. The brief window (~30–90 s) during
which no qwen3tts backend is available is covered by the Hermes kokoro
fallback leg already present in hal0-voice-tts.py.

Hermes bridge repoint

File: /var/lib/hal0/.hermes/scripts/hal0-voice-tts.py

Old default: QWEN3_URL = os.environ.get("QWEN3TTS_URL", "http://127.0.0.1:8095/v1/audio/speech")

New default: QWEN3_URL = os.environ.get("QWEN3TTS_URL", "http://127.0.0.1:8080/v1/audio/speech")

The QWEN3TTS_URL env-var override path is preserved for out-of-band
configuration. The hal0-voice {qwen3|kokoro} switch continues to work
unchanged (it reads tts_voice.conf, which is independent of the URL).

Live state verification

Zero live changes were made. Read-only commands run against CT105:

  • cat /etc/systemd/system/hal0-qwen3tts.service
  • systemctl status hal0-qwen3tts.service --no-pager
  • cat /var/lib/hal0/.hermes/scripts/hal0-voice-tts.py
  • cat /var/lib/hal0/.hermes/tts_voice.conf
  • grep "tts:" /var/lib/hal0/.hermes/config.yaml
  • cat /usr/local/bin/hal0-voice
  • curl -s http://127.0.0.1:8080/api/slots (read-only)
  • curl -s http://127.0.0.1:8080/api/slots/qwen3tts (read-only)
  • curl -s http://127.0.0.1:8095/health (read-only)
  • curl -s http://127.0.0.1:8080/v1/audio/speech ... -o /dev/null (read-only probe)

🤖 Generated with Claude Code

…ript

Prep-only: documents and automates the retirement of hal0-qwen3tts.service
(standalone podman TTS on :8095) once the hal0-native qwen3tts slot (PR #972)
is deployed and verified, and the Hermes TTS bridge is repointed to use the
hal0 front door (:8080/v1/audio/speech) instead.

Deliverables (NOT executed):
- handoffs/qwen3tts-standalone-to-slot-migration-2026-06-28.md — runbook
  covering preconditions, port-collision analysis, Hermes bridge repoint
  (QWEN3TTS_URL default: :8095 -> :8080), step-by-step cutover, and rollback.
- scripts/migrate-qwen3tts-to-slot.sh — idempotent, guarded migration script
  with --dry-run (default), --apply, --rollback; guards verify slot READY +
  /v1/audio/speech returns audio + kokoro fallback healthy before touching
  anything; all .hermes/ edits run as hal0 user (never root).

No live state changed. See runbook §9 for the read-only commands run against CT105.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thinmintdev thinmintdev enabled auto-merge (squash) June 29, 2026 02:21
@thinmintdev thinmintdev merged commit 75b0004 into main Jun 29, 2026
3 checks passed
thinmintdev added a commit that referenced this pull request Jun 29, 2026
Cuts the release that carries the qwen3tts work merged after 0.8.2b2:
Qwen3TTSProvider (#972), dispatcher upstream-auth (#973), voice.tts
capability switch (#976), toolbox image CI (#975), migration prep (#974),
and the pinned qwen3tts image digest (#977). All toolbox_images digests
are non-null, satisfying release.yml's null-digest gate.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant