feat(uno-q): LAN-open boot + Telegram self-serve + guided lockdown modalities

Boards now boot LAN-open (host 0.0.0.0, allow_public_bind, require_pairing=false)
so a team reaches its node's embedded ZeroClaw dashboard + web chat directly by
IP with no token — the 'Open your node' path. Two more modalities ride the same
default (cloud-first) agent:

- Telegram: config seeds [channels.telegram.default] disabled + pre-bound to the
  default agent; a team enables it from the dashboard by pasting a @BotFather
  token. Dashboard writes only set pending_reload, and /admin/reload is
  loopback-only, so a new zeroclaw-reload-watcher.sh (loopback) applies dashboard
  config edits within seconds — no shell. provision-fleet pushes + launches it.
- Lockdown: zeroclaw-lockdown.sh flips require_pairing=true, reloads, and mints a
  pair code (open -> locked harden step); documented as a board/adb action since
  minting + reload are loopback-only.
- Voice: seeds a commented [channels.voice_duplex.default] + documents the
  aarch64 build (embedded-web + gateway-voice-duplex); build/hardware work is
  separate.

Onboarding scripts (apess-selfregister.sh, provision-uno-q.sh) now tolerate
open-boot: when the gateway mints no pair code, they announce with a placeholder
token (the open board ignores auth) instead of hard-failing.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-07-15 16:35:28 -07:00
co-authored by Claude Opus 4.8
parent af9cae0abc
commit 7233a4b1c0
8 changed files with 273 additions and 24 deletions
+10 -4
View File
@@ -34,10 +34,16 @@ for _ in $(seq 1 60); do
done
# Pair locally for a bearer token (the token stays server-side once APESS has it).
CODE=$("$ZEROCLAW" gateway get-paircode --new --port "$PORT" | grep -oE '[0-9]{6}' | head -1)
TOKEN=$(curl -s -X POST "$GW/pair" -H "X-Pairing-Code: ${CODE}" \
| python3 -c 'import sys,json;print(json.load(sys.stdin).get("token",""))')
[ -n "$TOKEN" ] || { echo "local pairing failed" >&2; exit 1; }
# Under LAN-open setup (require_pairing=false) the gateway mints no code — the
# open board ignores auth, so announce with a placeholder token; lockdown later
# establishes real pairing (and, if wanted, re-announces a valid token).
CODE=$("$ZEROCLAW" gateway get-paircode --new --port "$PORT" 2>/dev/null | grep -oE '[0-9]{6}' | head -1 || true)
TOKEN=""
if [ -n "$CODE" ]; then
TOKEN=$(curl -s -X POST "$GW/pair" -H "X-Pairing-Code: ${CODE}" \
| python3 -c 'import sys,json;print(json.load(sys.stdin).get("token",""))' 2>/dev/null || true)
fi
TOKEN="${TOKEN:-open-lan}" # placeholder while the board is LAN-open
# The LAN IP participants (and APESS) reach; fall back to localhost for adb-only.
IP=$(ip -4 -o addr show 2>/dev/null | grep -oE 'inet [0-9.]+' | grep -v '127.0.0.1' \