From ea2eba76a6a7c937c7e16e45844da087d2a5d045 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Mon, 19 Oct 2026 02:30:33 -0700 Subject: [PATCH] ops(svos): v0.0.24 (supersedes the unpushed v0.0.23; U22 after review) staged on nh3-svos; two-card cutover playbooks ready --- configs/svos-apps/judge.toml | 4 +- .../nh3-svos-d14dc94-v0.0.24-interface.yaml | 29 ++++++++++ .../nh3-svos-d14dc94-v0.0.24-stage.yaml | 24 +++++++++ .../nh3-svos-d14dc94-v0.0.24.yaml | 53 +++++++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-interface.yaml create mode 100644 playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-stage.yaml create mode 100644 playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24.yaml diff --git a/configs/svos-apps/judge.toml b/configs/svos-apps/judge.toml index adc34c6..89f9c7c 100644 --- a/configs/svos-apps/judge.toml +++ b/configs/svos-apps/judge.toml @@ -1,4 +1,4 @@ -# /config/apps/judge.toml on nh3-svos — app-judge 0.0.1 (U19), from apps/judge/examples/judge.toml at v0.0.16; + explain_seconds for 0.0.2 (v0.0.23). +# /config/apps/judge.toml on nh3-svos — app-judge 0.0.1 (U19), from apps/judge/examples/judge.toml at v0.0.16; + explain_seconds for 0.0.2 (v0.0.24). # Prime 2026-10-18: drafting on gen-large (local, free); tasks may run on the six local chat models (the hermes runtime's # `models` in instance.toml). The gateway key (vault nh3-svos/svos-judge-gateway-key, LiteLLM alias svos-app-judge) is # scoped to exactly those six, so the /tasks model select offers exactly them. @@ -29,4 +29,4 @@ concurrency = 8 reply_bytes = 1048576 brief_bytes = 262144 health_seconds = 5 -explain_seconds = 60 # U22 (judge 0.0.2, v0.0.23): one deadline per explain call, the model call included; 5..60, the page waits 65 s +explain_seconds = 60 # U22 (judge 0.0.2, v0.0.24): one deadline per explain call, the model call included; 5..60, the page waits 65 s diff --git a/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-interface.yaml b/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-interface.yaml new file mode 100644 index 0000000..39fd6ee --- /dev/null +++ b/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-interface.yaml @@ -0,0 +1,29 @@ +# nh3-svos v0.0.24 step 2: restart ONLY svos-interface onto app-interface 0.0.8 (U22: verbs summaries + summary, namespace +# interface-summaries; the store state/apps/interface/summaries.sqlite3 is created at start). Raises a held card for +# app-interface: the WHOLE interface answers wrong-revision until Prime approves (about 30 s at v0.0.18). Run only after +# the judge's card is approved, with Prime at the board. Then Prime's two grants on ns:interface-summaries. +steps: + - name: current is d14dc94 and the judge's new revision is pinned + sudo: true + shell: | + readlink /opt/svos/current | grep -q d14dc94 + python3 -c " + import sqlite3 + c = sqlite3.connect('file:/var/lib/svos/state/svos.db?mode=ro', uri=True) + r = c.execute(\"select revision, state from app_manifests where slug='app-judge' order by revision desc limit 1\").fetchone(); print('judge', r) + assert r[1] == 'pinned', 'judge card not approved yet'" + changed_when: "false" + - name: Restart ONLY svos-interface (raises the held card) + sudo: true + shell: systemctl restart svos-interface; sleep 8; systemctl is-active svos-interface +verify: + - name: Interface on d14dc94; its manifest revision and card + sudo: true + shell: | + pid=$(systemctl show svos-interface -p MainPID --value); grep -q /opt/svos/releases/d14dc94 /proc/$pid/maps && echo "interface pid $pid on d14dc94" + python3 -c " + import sqlite3 + c = sqlite3.connect('file:/var/lib/svos/state/svos.db?mode=ro', uri=True) + for r in c.execute(\"select slug, revision, substr(sha256,1,12), state from app_manifests where slug='app-interface' order by revision desc limit 2\"): print(r) + for r in c.execute(\"select id, kind, state, created_at, expires_at from cards where slug='app-interface' and kind='manifest' order by created_at desc limit 1\"): print(r)" + changed_when: "false" diff --git a/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-stage.yaml b/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-stage.yaml new file mode 100644 index 0000000..ada1e7f --- /dev/null +++ b/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24-stage.yaml @@ -0,0 +1,24 @@ +# nh3-svos: STAGE SVOS v0.0.24 (d14dc94) beside the live release: kernel 0.0.24 (a version bump), app-judge 0.0.2 (U22 +# explain), app-interface 0.0.8 (U22 summaries), UI 0.0.28; everything else carried from 2f29d0d. Does NOT switch current, +# stop or start anything. svos-dev thread 01M59P4Z1VJ4WHJB0N8N1P743K. The cutover is nh3-svos-d14dc94-v0.0.24.yaml. +steps: + - name: Private staging dir + shell: install -d -m 0700 /tmp/svos-stage-d14dc94 + - {name: stage release, upload: {src: /tmp/claude-1000/-home-lkraven-development-eshpfi-management/e0be18fd-0734-4786-b933-904f0a74d2a2/scratchpad/svos-d14dc94/svos-release-d14dc94.tar.gz, dest: /tmp/svos-stage-d14dc94/release.tar.gz, mode: "0644"}} + - {name: stage uv, upload: {src: /home/lkraven/bin/uv, dest: /tmp/svos-stage-d14dc94/uv, mode: "0755"}} + - {name: stage installer, upload: {src: /tmp/claude-1000/-home-lkraven-development-eshpfi-management/e0be18fd-0734-4786-b933-904f0a74d2a2/scratchpad/svos-d14dc94/install-release.py, dest: /tmp/svos-stage-d14dc94/install-release.py, mode: "0644"}} + - name: Verify staged hashes + shell: cd /tmp/svos-stage-d14dc94 && printf '%s %s\n' 4259f7f97f554b1fba4c2fd172244a0d2bd6d36fe2eb203a404b95311d051f7d release.tar.gz 83aa128da93e168283ed32cf75cd819fe17b135b3fc1f7ccb3c912eec198d9fb uv | sha256sum -c - + changed_when: "false" + - name: Install release d14dc94 beside the live one (current NOT switched) + sudo: true + shell: python3 /tmp/svos-stage-d14dc94/install-release.py + creates: /opt/svos/releases/d14dc94/apps-env/pyvenv.cfg +verify: + - name: New kernel 0.0.24 accepts the live configuration as it is + sudo: true + shell: runuser -u svc-svos -- /opt/svos/releases/d14dc94/kernel-env/bin/svos-kernel check-config --data-root /var/lib/svos + changed_when: "false" + - name: current still points at the live release + shell: readlink /opt/svos/current + changed_when: "false" diff --git a/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24.yaml b/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24.yaml new file mode 100644 index 0000000..2c991b5 --- /dev/null +++ b/playbooks/svos-releases/nh3-svos-d14dc94-v0.0.24.yaml @@ -0,0 +1,53 @@ +# nh3-svos -> SVOS v0.0.24 (d14dc94), U22 card summaries. svos-dev thread 01M59P4Z1VJ4WHJB0N8N1P743K. +# PRE-REQS: the stage playbook; origin's v0.0.24 == d14dc94f6840 (git ls-remote on nh3-dev); Prime AT THE BOARD. +# This playbook does the release + the JUDGE (step 1 of svos-dev's order): backup, judge.toml explain_seconds, current, +# front door (UI 0.0.28), restart ONLY svos-judge -> a held card for app-judge (its reads refuse until approved: the task +# form's draft and admit wait). The INTERFACE restart is a separate playbook, run only after the judge's card is approved +# (nh3-svos-d14dc94-v0.0.24-interface.yaml). The kernel is NOT restarted (0.0.24 = 0.0.22 in code). No instance.toml change. +steps: + - name: Pre-reqs present + sudo: true + shell: test -f /opt/svos/releases/d14dc94/apps-env/bin/svos-judge && readlink /opt/svos/current && runuser -u svc-svos -- /opt/svos/releases/d14dc94/kernel-env/bin/svos-kernel check-config --data-root /var/lib/svos + changed_when: "false" + - name: Online backup to /var/lib/svos/backup/pre-d14dc94 (svos.db and the interface's stores) + sudo: true + shell: | + set -e + d=/var/lib/svos/backup/pre-d14dc94 + runuser -u svc-svos -- install -d -m 0700 $d + runuser -u svc-svos -- python3 -c " + import sqlite3, glob, os + for src in ['/var/lib/svos/state/svos.db'] + sorted(glob.glob('/var/lib/svos/state/apps/interface/*.sqlite3')): + dst = '$d/' + os.path.basename(src) + s = sqlite3.connect('file:' + src + '?mode=ro', uri=True); t = sqlite3.connect(dst); s.backup(t); t.close(); s.close() + c = sqlite3.connect('file:' + dst + '?mode=ro', uri=True); print(os.path.basename(src), 'integrity', c.execute('pragma integrity_check').fetchone()[0])" + runuser -u svc-svos -- cp -p /var/lib/svos/config/apps/judge.toml /var/lib/svos/config/apps/judge.toml.pre-d14dc94 + - {name: judge.toml with explain_seconds, upload: {src: configs/svos-apps/judge.toml, dest: /var/lib/svos/config/apps/judge.toml.new, mode: "0600"}, sudo: true} + - name: Swap judge.toml (owned by svc-svos) + sudo: true + shell: | + set -e + cd /var/lib/svos/config/apps + chown svc-svos:svc-svos judge.toml.new && mv judge.toml.new judge.toml && grep -n '^explain_seconds' judge.toml + - name: Switch current to d14dc94 + sudo: true + shell: ln -sfn /opt/svos/releases/d14dc94 /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: Front door inventory (UI 0.0.28 live; 2f29d0d becomes previous) + sudo: true + shell: /usr/local/sbin/svos-front-inventory 2>&1 | grep -E 'GENERATED|updated|root \*|path /assets' | head -4 + - name: Restart ONLY svos-judge (raises the held card for app-judge) + sudo: true + shell: | + systemctl restart svos-judge; sleep 6; systemctl is-active svos-judge + journalctl -u svos-judge --since "-30s" --no-pager -o cat | grep -iE "manifest|revision|held|error|config" | tail -5 | cut -c1-200 || true +verify: + - name: Judge on d14dc94; its manifest revision and card + sudo: true + shell: | + pid=$(systemctl show svos-judge -p MainPID --value); grep -q /opt/svos/releases/d14dc94 /proc/$pid/maps && echo "judge pid $pid on d14dc94" + python3 -c " + import sqlite3 + c = sqlite3.connect('file:/var/lib/svos/state/svos.db?mode=ro', uri=True) + for r in c.execute(\"select slug, revision, substr(sha256,1,12), state from app_manifests where slug='app-judge' order by revision desc limit 2\"): print(r) + for r in c.execute(\"select id, kind, state, created_at, expires_at from cards where slug='app-judge' and kind='manifest' order by created_at desc limit 1\"): print(r)" + changed_when: "false"