Config policies (16 files): alert_routing, architecture_pressure, backlog, cost_weights, data_governance, incident_escalation, incident_intelligence, network_allowlist, nodes_registry, observability_sources, rbac_tools_matrix, release_gate, risk_attribution, risk_policy, slo_policy, tool_limits, tools_rollout Ops (22 files): Caddyfile, calendar compose, grafana voice dashboard, deployments/incidents logs, runbooks for alerts/audit/backlog/incidents/sofiia/voice, cron jobs, scripts (alert_triage, audit_cleanup, migrate_*, governance, schedule), task_registry, voice alerts/ha/latency/policy Docs (30+ files): HUMANIZED_STEPAN v2.7-v3 changelogs and runbooks, NODA1/NODA2 status and setup, audit index and traces, backlog, incident, supervisor, tools, voice, opencode, release, risk, aistalk, spacebot Made-with: Cursor
158 lines
4.8 KiB
Markdown
158 lines
4.8 KiB
Markdown
# Voice Phase 2 Streaming — Cutover Plan
|
||
|
||
## Мета
|
||
|
||
Безпечно ввімкнути Phase 2 sentence-chunking streaming (`/api/voice/chat/stream`)
|
||
для **всіх голосових сесій** без регресій.
|
||
|
||
## Поточний стан (baseline)
|
||
|
||
| Метрика | Значення |
|
||
|---------|---------|
|
||
| TTS p95 | ~1536ms ✅ |
|
||
| gemma3 TTFA | ~2620ms ✅ |
|
||
| qwen3.5 TTFA | ~8524ms ✅ (auto-promote qualified) |
|
||
| qwen3:14b TTFA | ~11618ms ⚠ fallback only |
|
||
| Streaming | enabled by default (checkbox ON) |
|
||
|
||
---
|
||
|
||
## Stages
|
||
|
||
### Stage 0 — Pre-conditions (blockers)
|
||
|
||
Виконати **перед будь-яким Stage**:
|
||
|
||
```bash
|
||
# 1. Voice canary preflight
|
||
python3 ops/scripts/voice_canary.py --mode preflight
|
||
|
||
# 2. Contract tests
|
||
python3 -m pytest tests/test_voice_policy.py tests/test_voice_stream.py -v
|
||
|
||
# 3. Degradation state check
|
||
curl -s http://localhost:8002/api/voice/degradation_status | python3 -m json.tool
|
||
# Очікування: state = "ok"
|
||
```
|
||
|
||
**Блокери:**
|
||
- [ ] voice_canary preflight passed (Polina + Ostap OK)
|
||
- [ ] 45/45 tests green
|
||
- [ ] degradation_status state = "ok"
|
||
- [ ] edge-tts версія = 7.2.7 (`docker exec dagi-memory-service-node2 pip show edge-tts | grep Version`)
|
||
|
||
---
|
||
|
||
### Stage 1 — 5% canary (feature flag в UI)
|
||
|
||
Увімкнути `streamMode=true` за замовчуванням (вже є), але обмежити до 5% сесій через cookie.
|
||
|
||
Реалізація (мінімальна):
|
||
- BFF `/api/voice/chat/stream` вже є.
|
||
- UI вже має `streamMode` checkbox (ON за замовчуванням).
|
||
- Достатньо: **не блокувати**, але збирати метрики.
|
||
|
||
**Що моніторити (10 хвилин):**
|
||
```bash
|
||
# TTFA
|
||
curl -s http://localhost:8002/api/voice/degradation_status
|
||
|
||
# Логи
|
||
docker logs sofiia-console --tail 50 | grep "voice_stream ok"
|
||
|
||
# Underflows у browser console
|
||
_voiceStats()
|
||
```
|
||
|
||
**SLO Gate Stage 1:**
|
||
- `voice_ttfa_ms` p95 ≤ 6000ms (20% буфер)
|
||
- `voice_tts_first_ms` p95 ≤ 2500ms
|
||
- underflow_rate ≤ 5% (relaxed for canary)
|
||
- No `emergency` state in degradation_status
|
||
|
||
---
|
||
|
||
### Stage 2 — 50% rollout
|
||
|
||
Якщо Stage 1 пройшов 30 хвилин без SLO breach:
|
||
- Переконатись що streamMode ON за замовчуванням.
|
||
- Включити polling деградації (`_startDegradPolling` — вже активний).
|
||
|
||
**Що додатково перевірити:**
|
||
```bash
|
||
# Grafana dashboard (імпортувати ops/grafana_voice_dashboard.json)
|
||
# Перевірити панелі 1-4 на наявність spike-ів
|
||
|
||
# Voice latency audit
|
||
bash ops/voice_latency_audit.sh 2>&1 | tail -30
|
||
```
|
||
|
||
---
|
||
|
||
### Stage 3 — 100% (production default)
|
||
|
||
Умови:
|
||
- Stage 2 стабільний ≥ 2 години
|
||
- Усі алерти (ops/voice_alerts.yml) в стані "OK" (не firing)
|
||
- `voice_queue_underflows_total` rate ≤ 0.017/s (1/хв)
|
||
|
||
**Дії:**
|
||
1. Переконатись `streamMode` checkbox: `checked` by default — вже є.
|
||
2. Додати voice_canary у ops/cron/jobs.cron — вже є.
|
||
3. Задеплоїти ops/voice_alerts.yml у Prometheus.
|
||
|
||
---
|
||
|
||
## Rollback план
|
||
|
||
Якщо будь-який SLO breach або degradation state ≠ ok:
|
||
|
||
```bash
|
||
# 1. Негайний rollback: вимкнути stream mode у BFF
|
||
# (без rebuild — через env var)
|
||
docker exec sofiia-console env | grep VOICE_STREAM_DISABLED
|
||
# Або через конфіг — додати VOICE_STREAM_DISABLED=true і перезапустити
|
||
|
||
# 2. Перевірити стан
|
||
curl -s http://localhost:8002/api/voice/degradation_status
|
||
python3 ops/scripts/voice_canary.py --mode preflight
|
||
|
||
# 3. Якщо TTS деградував — перезапустити memory-service
|
||
docker restart dagi-memory-service-node2
|
||
sleep 10 && curl -s http://localhost:8000/voice/health
|
||
```
|
||
|
||
**Fallback chain (автоматичний):**
|
||
1. TTFA p95 > 5s → badge "⚠ AI SLOW", profile stays fast
|
||
2. TTFA p95 > 8s → badge "⚡ FAST MODE", voiceQuality checkbox auto-unchecked
|
||
3. TTS p95 > 2s → badge "⚠ TTS SLOW"
|
||
4. TTS p95 > 4s → badge "🔴 TTS DEGRADED", user informed
|
||
|
||
---
|
||
|
||
## Feature Flag (якщо потрібен explicit ON/OFF)
|
||
|
||
Додати в `docker-compose.node2-sofiia.yml` → environment:
|
||
|
||
```yaml
|
||
VOICE_STREAM_ENABLED: "true" # або "false" для rollback
|
||
```
|
||
|
||
Та в `main.py` `/api/voice/chat/stream`:
|
||
```python
|
||
if not os.getenv("VOICE_STREAM_ENABLED", "true").lower() == "true":
|
||
raise HTTPException(503, "Voice streaming disabled")
|
||
```
|
||
|
||
---
|
||
|
||
## Метрики для Phase 2 auto-approve
|
||
|
||
voice_policy_update.py читає ops/voice_canary_last.json + Prometheus і автоматично:
|
||
1. Оновлює `auto_promote` пороги в router-config.yml
|
||
2. Генерує ops/voice_latency_report.json
|
||
|
||
```bash
|
||
python3 ops/voice_policy_update.py --apply
|
||
```
|