#!/bin/sh # The live acceptance of the operator's answers (novox/hq ADR 0259), after rollout, at the controller's # terminal on the control node. The lab's proof (TestTheOperatorsAnswerEndToEnd) ran the same flow with a fake # Telegram; this runs it once for real, with a question that changes nothing. # # sh live-acceptance.sh check, ask the rehearsal, wait for the answer, read the record # # It reads and asks only: no setting, assignment or push. The one thing it starts is a rehearsal, a question the # operator answers on the phone; approving it performs nothing and is recorded as the operator's decision. # # It stops at the first check that fails and says what to do. Exit 0 means: the question reached the phone # with Approve and Decline, the answer came back as a warrant, and the hand-act log names who answered, # through which channel, with which proofs. set -eu # mesh-cli asks the controller; on the control node, from the operator's own account, a line is the # controller's terminal (ADR 0272). `nox` is its interactive alias; a script says mesh-cli. mc=${MESH_CLI:-mesh-cli} stop() { echo "NOT ACCEPTED: $*"; exit 1; } echo "1. Nothing open says the router's or Telegram's machine is not root-free (root-not-free, agent-root)." if $mc conditions | grep -q 'root-not-free\|agent-root'; then $mc conditions | grep 'root-not-free\|agent-root' stop "while an agent can become root there, Telegram only acknowledges; close it first (ADR 0266, ADR 0268)" fi echo "2. The Telegram channel holds a working bot token and its updates arrive." tg=$($mc ask telegram telegram_status) || stop "the telegram module does not answer" echo "$tg" | grep -q '"can_send": *true' || { echo "$tg"; stop "Telegram cannot send now (why_not above): give the bot token again at the controller's terminal (hq ADR 0259, the operator's steps), then push the control node"; } echo "3. One Telegram account is linked as the operator, and its hour has passed." ids=$($mc ask messenger messenger_identities) || stop "the router does not answer" echo "$ids" echo "$ids" | grep -q '"telegram"' || stop "no Telegram account is linked: send /start to the bot, then the code from the desk" # The router answers approvals from a new link only an hour after it was made (ADR 0259 §7): said here, with the # time, rather than seen as a rehearsal nobody's approval reaches. from=$(echo "$ids" | tr -d '\n ' | grep -o '"kind":"telegram"[^}]*' | grep -o '"approve-from":"[^"]*"' | cut -d'"' -f4 | head -n 1) [ -n "$from" ] || stop "the router's word on the Telegram account says no time it can approve from" starts=$(date -d "$from" +%s 2>/dev/null) || stop "the time the Telegram account can approve from is not a time: $from" if [ "$(date +%s)" -lt "$starts" ]; then stop "the Telegram account was linked less than an hour ago — approvals start at $(date -d "$from" '+%H:%M') (local time); run this again then" fi echo "4. The rehearsal: a question on your phone. Approve it there within 15 minutes." said=$($mc rehearse --for 15m) || stop "the rehearsal could not be asked" echo "$said" id=$(echo "$said" | sed -n 's/^rehearsal \([A-Za-z0-9_-]*\) asked.*/\1/p') [ -n "$id" ] || stop "the rehearsal did not say its id" echo "5. Waiting for your answer in the hand-act log (every 10 s, at most 16 minutes)." i=0 while [ $i -lt 96 ]; do acts=$($mc hand-acts --days 1 --json 2>/dev/null || true) mine=$(echo "$acts" | tr -d '\n' | grep -o "{[^{}]*\"ask\": *\"$id\"[^{}]*}" || true) if [ -n "$mine" ]; then echo "$mine" echo "$mine" | grep -q 'rehearsal=decline' && stop "the rehearsal was declined: run it again and choose Approve to see an approval recorded" echo "$mine" | grep -q 'rehearsal=approve' || stop "the rehearsal's record names no approval" echo "$mine" | grep -q '"via": *"telegram (telegram), user id verified"' || stop "the record does not say the answer came through Telegram from a verified account" echo "$mine" | grep -q '"P1"' || stop "the record does not carry the proof" echo "$mine" | grep -q '"outcome": *"done"' || stop "the rehearsal's act did not end done" echo "ACCEPTED: the rehearsal was approved on Telegram, acted on once, and recorded as your decision." exit 0 fi i=$((i + 1)) sleep 10 done stop "no answer was recorded within 16 minutes: check messenger_status and telegram_status"