From fa2895c45b9276237a8eee537642d44a986a088c Mon Sep 17 00:00:00 2001 From: twentyOne2x Date: Sat, 20 Jun 2026 13:03:10 +0200 Subject: [PATCH] Add Leo test deploy readiness check --- deploy/check-leo-test-deploy-readiness.sh | 114 ++++++++++++++++++++++ docs/leo-test-deploy-readiness.md | 72 ++++++++++++++ 2 files changed, 186 insertions(+) create mode 100755 deploy/check-leo-test-deploy-readiness.sh create mode 100644 docs/leo-test-deploy-readiness.md diff --git a/deploy/check-leo-test-deploy-readiness.sh b/deploy/check-leo-test-deploy-readiness.sh new file mode 100755 index 0000000..8372677 --- /dev/null +++ b/deploy/check-leo-test-deploy-readiness.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +# Read-only readiness check for the disposable Leo Telegram transport. +# Run on the VPS before resetting auto-deploy or booting teleo-agent@leo-test. +set -euo pipefail + +DEPLOY_CHECKOUT="${DEPLOY_CHECKOUT:-/opt/teleo-eval/workspaces/deploy}" +DEPLOY_INFRA_CHECKOUT="${DEPLOY_INFRA_CHECKOUT:-/opt/teleo-eval/workspaces/deploy-infra}" +RUNTIME_TELEGRAM_DIR="${RUNTIME_TELEGRAM_DIR:-/opt/teleo-eval/telegram}" +PIPELINE_TELEGRAM_DIR="${PIPELINE_TELEGRAM_DIR:-/opt/teleo-eval/pipeline/telegram}" +LEO_TEST_TOKEN_FILE="${LEO_TEST_TOKEN_FILE:-/opt/teleo-eval/secrets/leo-test-telegram-bot-token}" +EXPECTED_GITHUB_MAIN="${EXPECTED_GITHUB_MAIN:-4cc6a5d06e053d95b3bc64eb359c9d07e2611b0c}" +EXPECTED_AUTO_DEPLOY_EXEC="${EXPECTED_AUTO_DEPLOY_EXEC:-/opt/teleo-eval/workspaces/deploy-infra/deploy/auto-deploy.sh}" +FETCH_GITHUB_MAIN="${FETCH_GITHUB_MAIN:-0}" + +failures=0 + +emit() { + printf '%s=%s\n' "$1" "$2" +} + +pass() { + emit "$1" "ok" +} + +fail() { + emit "$1" "missing_or_mismatch" + emit "$1.reason" "$2" + failures=$((failures + 1)) +} + +check_file_present() { + local key="$1" + local path="$2" + if [ -f "$path" ]; then + pass "$key" + else + fail "$key" "$path not found" + fi +} + +emit schema livingip.teleo.leoTestDeployReadiness.v1 +emit secret_values_included false +emit live_service_reset_run false +emit telegram_or_slack_message_sent false +emit paid_spend_run false + +if [ ! -d "$DEPLOY_CHECKOUT/.git" ]; then + fail deploy_checkout_git "$DEPLOY_CHECKOUT/.git not found" +else + pass deploy_checkout_git + emit deploy_checkout_path "$DEPLOY_CHECKOUT" + emit deploy_checkout_branch "$(git -C "$DEPLOY_CHECKOUT" rev-parse --abbrev-ref HEAD 2>/dev/null || true)" + emit deploy_checkout_head "$(git -C "$DEPLOY_CHECKOUT" rev-parse --short HEAD 2>/dev/null || true)" + emit deploy_checkout_status "$(git -C "$DEPLOY_CHECKOUT" status --short | tr '\n' ';' || true)" +fi + +if [ ! -d "$DEPLOY_INFRA_CHECKOUT/.git" ]; then + fail deploy_infra_git "$DEPLOY_INFRA_CHECKOUT/.git not found" +else + pass deploy_infra_git + emit deploy_infra_path "$DEPLOY_INFRA_CHECKOUT" + if [ "$FETCH_GITHUB_MAIN" = "1" ]; then + git -C "$DEPLOY_INFRA_CHECKOUT" fetch github main --quiet 2>/dev/null || true + emit deploy_infra_fetch_github_main attempted + else + emit deploy_infra_fetch_github_main skipped + fi + github_main="$(git -C "$DEPLOY_INFRA_CHECKOUT" rev-parse github/main 2>/dev/null || true)" + emit deploy_infra_github_main "$github_main" + if [ "$github_main" = "$EXPECTED_GITHUB_MAIN" ]; then + pass deploy_infra_github_main_expected + else + fail deploy_infra_github_main_expected "expected $EXPECTED_GITHUB_MAIN, got ${github_main:-none}" + fi + + if git -C "$DEPLOY_INFRA_CHECKOUT" cat-file -e github/main:telegram/agents/leo-test.yaml 2>/dev/null; then + pass deploy_infra_github_main_leo_test_config + else + fail deploy_infra_github_main_leo_test_config "github/main lacks telegram/agents/leo-test.yaml" + fi + + if git -C "$DEPLOY_INFRA_CHECKOUT" cat-file -e github/main:deploy/auto-deploy.sh 2>/dev/null; then + pass deploy_infra_github_main_auto_deploy + else + fail deploy_infra_github_main_auto_deploy "github/main lacks deploy/auto-deploy.sh" + fi +fi + +actual_exec="$(systemctl cat teleo-auto-deploy.service 2>/dev/null | awk -F= '/^ExecStart=/{print $2; exit}' || true)" +emit teleo_auto_deploy_exec_start "$actual_exec" +if [ "$actual_exec" = "$EXPECTED_AUTO_DEPLOY_EXEC" ]; then + pass teleo_auto_deploy_exec_start_expected +else + fail teleo_auto_deploy_exec_start_expected "expected $EXPECTED_AUTO_DEPLOY_EXEC, got ${actual_exec:-none}" +fi + +check_file_present runtime_leo_config "$RUNTIME_TELEGRAM_DIR/agents/leo.yaml" +check_file_present runtime_leo_test_config "$RUNTIME_TELEGRAM_DIR/agents/leo-test.yaml" +check_file_present pipeline_leo_test_config "$PIPELINE_TELEGRAM_DIR/agents/leo-test.yaml" + +if [ -f "$LEO_TEST_TOKEN_FILE" ]; then + pass leo_test_token_file +else + fail leo_test_token_file "$LEO_TEST_TOKEN_FILE not found" +fi + +if [ "$failures" -eq 0 ]; then + emit status ready_for_leo_test_validate_and_boot +else + emit status blocked + emit failure_count "$failures" +fi + +exit "$failures" diff --git a/docs/leo-test-deploy-readiness.md b/docs/leo-test-deploy-readiness.md new file mode 100644 index 0000000..25eaa75 --- /dev/null +++ b/docs/leo-test-deploy-readiness.md @@ -0,0 +1,72 @@ +# Leo Test Deploy Readiness + +## Working Target + +Confirm the VPS is ready to boot the disposable `teleo-agent@leo-test` service +without touching production Leo, sending Telegram/Slack messages, resetting +services, or reading token contents. + +## Why + +PR #5 added `telegram/agents/leo-test.yaml`, but the VPS deploy source can lag +behind GitHub. The readiness check keeps the next live step explicit: source +reconciliation first, token file second, service validation and boot third. + +## Command + +Run on the VPS: + +```sh +/opt/teleo-eval/workspaces/deploy-infra/deploy/check-leo-test-deploy-readiness.sh +``` + +The checker is read-only. It prints `key=value` rows and exits non-zero until +all required state is present. + +By default it does not fetch or update Git refs. To explicitly refresh +`github/main` before checking, run: + +```sh +FETCH_GITHUB_MAIN=1 /opt/teleo-eval/workspaces/deploy-infra/deploy/check-leo-test-deploy-readiness.sh +``` + +## Expected Blockers Before Reconciliation + +The current blocker set should include: + +- `teleo_auto_deploy_exec_start_expected`: systemd still points at the legacy + `/opt/teleo-eval/workspaces/deploy/ops/auto-deploy.sh` path. +- `runtime_leo_test_config`: runtime Telegram path does not yet have + `agents/leo-test.yaml`. +- `pipeline_leo_test_config`: pipeline Telegram mirror does not yet have + `agents/leo-test.yaml`. +- `leo_test_token_file`: `/opt/teleo-eval/secrets/leo-test-telegram-bot-token` + is absent. + +## Ready State + +The checker returns: + +```text +status=ready_for_leo_test_validate_and_boot +``` + +only after: + +- deploy-infra can fetch GitHub main at the expected PR #5 merge commit; +- GitHub main contains `telegram/agents/leo-test.yaml`; +- systemd points auto-deploy at the reviewed deploy-infra script; +- runtime and pipeline Telegram paths contain `agents/leo-test.yaml`; +- the separate disposable test bot token file exists. + +## Next Live Step After Ready + +After readiness passes, validate without sending a message: + +```sh +sudo -u teleo /opt/teleo-eval/pipeline/.venv/bin/python3 \ + /opt/teleo-eval/telegram/agent_runner.py --agent leo-test --validate +``` + +Only after that should `teleo-agent@leo-test` be started for a private, +explicitly authorized disposable bot DM test.