Files
esh-pfi-infrastructure/playbooks/svos-releases/nh3-svos-15c2d04-v0.0.17.yaml
T

81 lines
5.8 KiB
YAML

# nh3-svos -> SVOS v0.0.17 (15c2d04): kernel 0.0.17 (U17 seat activity: [[seats.runtimes]] prompt/working/window, the
# row's `activity`, seat/activity_changed) and UI 0.0.21 (the working flow; the voice client admits 0.1..120 s and speaks
# long text in pieces). Prime 2235 2026-10-18 via svos-dev (thread 01M595YP8R62Y665C38MHPH6YX): "deploy v0.0.17 now".
# PRE-REQ: nh3-svos-15c2d04-v0.0.17-stage.yaml. No schema change (14). An old kernel refuses the new runtime keys, so the
# edit lands inside the stopped window: stop; backup; switch; edit (verbatim from docs/operations/u13-edit-payload.md
# @15c2d04) + check-config (restore + b51aa5e on refusal); start; front door; then voice.toml utterance_seconds 30 -> 60
# (UI 0.0.21 is live by then) and the voice app starts last. nh3-dev's terminal 0.0.6 is a separate playbook (one card).
steps:
- name: Pre-reqs present (release staged, edit script staged, no runtime keys yet)
sudo: true
shell: test -f /opt/svos/releases/15c2d04/kernel-env/bin/svos-kernel && test -f /tmp/svos-stage-15c2d04/u17-runtimes-edit.py && ! grep -qE '^(prompt|working|window) *=' /var/lib/svos/config/instance.toml && readlink /opt/svos/current
changed_when: "false"
- name: Stop the local apps then the kernel
sudo: true
shell: systemctl stop svos-voice svos-judge svos-knowledge svos-interface svos-kernel; systemctl is-active svos-kernel svos-interface svos-knowledge svos-judge svos-voice | tr '\n' ' '; echo
- name: Offline backup to /var/lib/svos/backup/pre-15c2d04
sudo: true
shell: |
set -e
d=/var/lib/svos/backup/pre-15c2d04
runuser -u svc-svos -- install -d -m 0700 $d
runuser -u svc-svos -- python3 -c "
import sqlite3
s = sqlite3.connect('/var/lib/svos/state/svos.db'); t = sqlite3.connect('$d/svos.db'); s.backup(t); t.close(); s.close()
c = sqlite3.connect('file:$d/svos.db?mode=ro', uri=True); print('integrity', c.execute('pragma integrity_check').fetchone()[0], 'user_version', c.execute('pragma user_version').fetchone()[0])"
runuser -u svc-svos -- cp -p /var/lib/svos/config/instance.toml /var/lib/svos/config/instance.toml.pre-15c2d04
runuser -u svc-svos -- cp -p /var/lib/svos/config/apps/voice.toml /var/lib/svos/config/apps/voice.toml.pre-15c2d04
- name: Switch current to 15c2d04
sudo: true
shell: ln -sfn /opt/svos/releases/15c2d04 /opt/svos/current.new && chgrp -h svc-svos /opt/svos/current.new && mv -T /opt/svos/current.new /opt/svos/current && readlink /opt/svos/current
- name: Config - the six runtimes' prompt/working/window (verbatim); the new kernel must accept it (else restore + b51aa5e)
sudo: true
shell: |
runuser -u svc-svos -- python3 - < /tmp/svos-stage-15c2d04/u17-runtimes-edit.py || exit 1 # stdin: svc-svos cannot read infra-ops's 0700 stage dir
if runuser -u svc-svos -- /opt/svos/releases/15c2d04/kernel-env/bin/svos-kernel check-config --data-root /var/lib/svos; then exit 0; fi
runuser -u svc-svos -- cp -p /var/lib/svos/config/instance.toml.pre-15c2d04 /var/lib/svos/config/instance.toml
ln -sfn /opt/svos/releases/b51aa5e /opt/svos/current.new && chgrp -h svc-svos /opt/svos/current.new && mv -T /opt/svos/current.new /opt/svos/current
systemctl start svos-kernel.service svos-interface svos-knowledge svos-judge svos-voice; echo "RESTORED config + b51aa5e"; exit 1
- name: Start the kernel then interface, knowledge, judge
sudo: true
shell: |
t0=$(date +%s.%N); systemctl start svos-kernel.service; rc=$?; t1=$(date +%s.%N)
echo "kernel start rc=$rc after $(python3 -c "print(round($t1-$t0,2))") s"
systemctl start svos-interface svos-knowledge svos-judge
sleep 8; curl -s http://127.0.0.1:8400/health; echo
- name: Front door inventory (UI 0.0.21 live; b51aa5e becomes previous)
sudo: true
shell: /usr/local/sbin/svos-front-inventory 2>&1 | grep -E 'GENERATED|updated|root \*|path /assets' | head -4
- name: voice.toml utterance_seconds 30 -> 60 (the 0.0.21 client admits 0.1..120), then start the voice app
sudo: true
shell: |
set -e
runuser -u svc-svos -- python3 - <<'PY'
import os
p = "/var/lib/svos/config/apps/voice.toml"; s = open(p, encoding="utf-8").read()
old = [l for l in s.split("\n") if l.startswith("utterance_seconds = 30 ")]
assert len(old) == 1, old
new = "utterance_seconds = 60 # 2026-10-18 v0.0.17: UI 0.0.21's voice client admits 0.1..120 s (U12 v1.4); 6 MiB output holds 65 s at 48 kHz"
s = s.replace(old[0], new)
t = p + ".tmp"; fd = os.open(t, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
with os.fdopen(fd, "w", encoding="utf-8") as f: f.write(s)
os.replace(t, p); print("edited")
PY
grep -n '^utterance_seconds' /var/lib/svos/config/apps/voice.toml
systemctl start svos-voice; sleep 5; systemctl is-active svos-voice
journalctl -u svos-voice --since "-30s" --no-pager -o cat | grep -iE "error|refus|invalid|limit" | tail -4 | cut -c1-200 || true
verify:
- name: Health ok, nothing down
shell: h=$(curl -s http://127.0.0.1:8400/health); echo "$h"; echo "$h" | grep -q '"status":"ok"' && echo "$h" | grep -q '"down":0'
changed_when: "false"
- name: Every app and the kernel run from 15c2d04
sudo: true
shell: |
for u in svos-kernel svos-interface svos-knowledge svos-judge svos-voice; do pid=$(systemctl show $u -p MainPID --value); printf '%s pid %s %s\n' $u $pid "$(grep -oE '/opt/svos/releases/[0-9a-f]+' /proc/$pid/maps | sort -u | tr '\n' ' ')"; done
for u in svos-kernel svos-interface svos-knowledge svos-judge svos-voice; do pid=$(systemctl show $u -p MainPID --value); grep -q /opt/svos/releases/15c2d04 /proc/$pid/maps || { echo "$u NOT on 15c2d04"; exit 1; }; done
changed_when: "false"
- name: Front door inventory current
sudo: true
shell: /usr/local/sbin/svos-front-inventory --check
changed_when: "false"