name: Unit Test V1

on:
  workflow_dispatch:
    inputs:
      tags:
        description: "Version"

env:
  CI_VERSION: "1.0.0"
  REPO_KUN: ${{ github.repository_owner }}/kun
  REPO_XUN: ${{ github.repository_owner }}/xun
  REPO_GOU: ${{ github.repository_owner }}/gou

  YAO_DEV: ${{ github.WORKSPACE }}
  YAO_ENV: development
  YAO_ROOT: ${{ github.WORKSPACE }}/../app
  YAO_HOST: 0.0.0.0
  YAO_PORT: 5099
  YAO_SESSION: "memory"
  YAO_LOG: "./logs/application.log"
  YAO_LOG_MODE: "TEXT"
  YAO_JWT_SECRET: "bLp@bi!oqo-2U+hoTRUG"
  YAO_DB_AESKEY: "ZLX=T&f6refeCh-ro*r@"

  YAO_EXTENSION_ROOT: ${{ github.WORKSPACE }}/../extension
  YAO_TEST_APPLICATION: ${{ github.WORKSPACE }}/../app

  YAO_RUNTIME_MIN: 3
  YAO_RUNTIME_MAX: 6
  YAO_RUNTIME_HEAP_LIMIT: 1500000000
  YAO_RUNTIME_HEAP_RELEASE: 10000000
  YAO_RUNTIME_HEAP_AVAILABLE: 550000000
  YAO_RUNTIME_PRECOMPILE: true

  MYSQL_TEST_HOST: "127.0.0.1"
  MYSQL_TEST_PORT: "3308"
  MYSQL_TEST_USER: "test"
  MYSQL_TEST_PASS: "123456"

  REDIS_TEST_HOST: "127.0.0.1"
  REDIS_TEST_PORT: "6379"
  REDIS_TEST_DB: "2"

  MONGO_TEST_HOST: "127.0.0.1"
  MONGO_TEST_PORT: "27017"
  MONGO_TEST_USER: "root"
  MONGO_TEST_PASS: "123456"

  PG_TEST_HOST: "127.0.0.1"
  PG_TEST_PORT: "5432"
  PG_TEST_USER: "test"
  PG_TEST_PASS: "123456"

jobs:
  # =============================================================================
  # Environment Setup & Verification
  # Build Yao, start services, connect Tai via gRPC tunnel, verify everything.
  # No tests are run — this job validates the CI environment is healthy.
  # =============================================================================
  setup-and-verify:
    runs-on: ubuntu-latest
    services:
      mongodb:
        image: mongo:6.0
        ports:
          - 27017:27017
        env:
          MONGO_INITDB_ROOT_USERNAME: root
          MONGO_INITDB_ROOT_PASSWORD: 123456
          MONGO_INITDB_DATABASE: test

      postgres:
        image: postgres:14
        ports:
          - 5432:5432
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: 123456
          POSTGRES_DB: test
        options: >-
          --health-cmd="pg_isready -U test"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5

    strategy:
      matrix:
        go: ["1.25"]

    steps:
      # ==== Phase 1: Checkout & Setup ====
      - name: Checkout Yao
        uses: actions/checkout@v4

      - name: Setup Build Environment
        uses: ./.github/actions/setup-yao
        with:
          repo-kun: ${{ env.REPO_KUN }}
          repo-xun: ${{ env.REPO_XUN }}
          repo-gou: ${{ env.REPO_GOU }}
          checkout-init: "true"
          apple-private-key: ${{ secrets.APPLE_PRIVATE_KEY_USER }}

      - name: Load sandbox-v2 env
        run: grep -vE '^\s*#|^\s*$' .github/env/sandbox-v2.env >> $GITHUB_ENV

      - name: Setup SQLite
        run: |
          mkdir -p ${{ github.WORKSPACE }}/../app/db
          echo "YAO_DB_PRIMARY=${{ github.WORKSPACE }}/../app/db/yao.db" >> $GITHUB_ENV

      - name: Start MySQL 8.0
        run: |
          docker run -d --name mysql \
            -e MYSQL_RANDOM_ROOT_PASSWORD=true \
            -e MYSQL_USER=${MYSQL_TEST_USER} \
            -e MYSQL_PASSWORD=${MYSQL_TEST_PASS} \
            -e MYSQL_DATABASE=test \
            -p ${MYSQL_TEST_PORT}:3306 \
            mysql:8.0 --port=3306 --sql-mode='' \
            --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

          for i in $(seq 1 30); do
            if docker exec mysql mysqladmin ping -h 127.0.0.1 -u ${MYSQL_TEST_USER} -p${MYSQL_TEST_PASS} > /dev/null 2>&1; then
              echo "MySQL ready"
              break
            fi
            echo "Waiting for MySQL... ($i/30)"
            sleep 2
          done

      - name: Start Redis
        run: docker run --name redis -d -p 6379:6379 redis:6

      # ==== Phase 2: Code Quality & Build ====
      - name: Code Quality Check
        run: |
          make vet
          make fmt-check

      - name: Build Yao
        run: go build -v -o $RUNNER_TEMP/yao .

      - name: Build ci-token
        run: go build -tags ci -v -o $RUNNER_TEMP/ci-token ./cmd/ci-token

      - name: Extract tai binary from image
        run: |
          CID=$(docker create yaoapp/tai:latest)
          docker cp "$CID":/usr/local/bin/tai $RUNNER_TEMP/tai
          docker rm "$CID"
          chmod +x $RUNNER_TEMP/tai
          $RUNNER_TEMP/tai version || echo "tai binary extracted"

      # ==== Phase 3: Prepare & Start Yao ====
      - name: Prepare test app directory
        run: |
          cp -r ${{ github.WORKSPACE }}/../yao-init $RUNNER_TEMP/yao-test-app
          mkdir -p $RUNNER_TEMP/yao-test-app/db

      - name: Start Yao server
        run: |
          cd $RUNNER_TEMP/yao-test-app
          YAO_ROOT=$(pwd) \
          YAO_HOST=0.0.0.0 \
          YAO_PORT=5099 \
          YAO_GRPC_HOST=0.0.0.0 \
          YAO_GRPC_PORT=9099 \
          YAO_DB_DRIVER=sqlite3 \
          YAO_DB_PRIMARY=$(pwd)/db/yao.db \
          YAO_SESSION=memory \
          YAO_ENV=development \
          YAO_JWT_SECRET="${{ env.YAO_JWT_SECRET }}" \
          YAO_DB_AESKEY="${{ env.YAO_DB_AESKEY }}" \
          $RUNNER_TEMP/yao start &

          # Wait for Yao HTTP to be ready (up to 120s)
          for i in $(seq 1 60); do
            if curl -sf http://127.0.0.1:5099/.well-known/yao > /dev/null 2>&1; then
              echo "Yao HTTP ready"
              curl -s http://127.0.0.1:5099/.well-known/yao | jq .
              break
            fi
            echo "Waiting for Yao... ($i/60)"
            sleep 2
          done

          curl -sf http://127.0.0.1:5099/.well-known/yao > /dev/null 2>&1 || {
            echo "::error::Yao HTTP failed to start"
            exit 1
          }

      # ==== Phase 4: Generate Tai credentials ====
      - name: Generate Tai credentials
        run: |
          gen_cred() {
            local CID=$1 TID=$2 OUT=$3
            local TOKEN
            TOKEN=$($RUNNER_TEMP/ci-token \
              --app $RUNNER_TEMP/yao-test-app \
              --client-id "$CID" \
              --subject "${YAO_CI_OAUTH_SUBJECT:-ci-tai}" \
              --user-id "${YAO_CI_OAUTH_USER_ID}" \
              --team-id "${YAO_CI_OAUTH_TEAM_ID}" \
              --scope "${YAO_CI_OAUTH_SCOPE:-tai:tunnel}" \
              --ttl "${YAO_CI_OAUTH_TTL:-24h}" 2>/dev/null | tail -1 | tr -d '[:space:]')

            local JSON="{\"client_id\":\"$CID\",\"tai_id\":\"$TID\",\"machine_id\":\"ci-runner\",\"server\":\"http://127.0.0.1:${YAO_CI_HTTP_PORT}\",\"yao_grpc_addr\":\"127.0.0.1:${YAO_CI_GRPC_PORT}\",\"access_token\":\"$TOKEN\",\"scope\":\"${YAO_CI_OAUTH_SCOPE}\",\"expires_at\":\"2099-01-01T00:00:00Z\",\"registered\":true}"
            echo -n "$JSON" | base64 -w0 > "$OUT"
            echo ""
            echo "Credentials JSON (debug): $JSON" | head -c 200
            echo "..."
            echo "Generated credentials for $CID → $OUT"
          }

          gen_cred tai-ci-local    tai-local-001    $RUNNER_TEMP/tai-local-credentials
          gen_cred tai-ci-docker   tai-docker-001   $RUNNER_TEMP/tai-docker-credentials
          gen_cred tai-ci-k8s      tai-k8s-001      $RUNNER_TEMP/tai-k8s-credentials
          gen_cred tai-ci-hostexec tai-hostexec-001  $RUNNER_TEMP/tai-hostexec-credentials

      # ==== Phase 5: Pull images & Setup K8s ====
      - name: Pull test images
        run: |
          docker pull yaoapp/tai-sandbox-test:latest || true
          docker pull yaoapp/tai:latest
          docker pull alpine:latest

      - name: Install k3d & create cluster
        run: |
          curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
          k3d cluster create tai-test --no-lb --wait --api-port ${YAO_CI_K3D_API_PORT}
          kubectl wait --for=condition=Ready node --all --timeout=60s
          k3d image import alpine:latest -c tai-test

      - name: Generate kubeconfig
        run: |
          K3D_IP=$(docker inspect k3d-tai-test-server-0 | jq -r '.[0].NetworkSettings.Networks["k3d-tai-test"].IPAddress')
          echo "k3d server IP: ${K3D_IP}"

          k3d kubeconfig get tai-test > /tmp/kubeconfig-k3d.yml

          # For tai-k8s container (uses k3d internal IP)
          sed "s|server: .*|server: https://${K3D_IP}:6443|" /tmp/kubeconfig-k3d.yml \
            > /tmp/kubeconfig-tai-k8s.yml
          echo "Container kubeconfig server:"
          grep server: /tmp/kubeconfig-tai-k8s.yml

          # For test runner (uses localhost via k3d port-mapped API)
          sed "s|server: .*|server: https://127.0.0.1:${YAO_CI_K3D_API_PORT}|" /tmp/kubeconfig-k3d.yml \
            > $RUNNER_TEMP/kubeconfig-tai.yml
          echo "Test runner kubeconfig server:"
          grep server: $RUNNER_TEMP/kubeconfig-tai.yml

          # Export for later steps
          echo "TAI_TEST_KUBECONFIG=$RUNNER_TEMP/kubeconfig-tai.yml" >> $GITHUB_ENV
          echo "YAO_CI_TAI_KUBECONFIG=$RUNNER_TEMP/kubeconfig-tai.yml" >> $GITHUB_ENV

      # ==== Phase 6: Start Tai instances (host processes) ====
      - name: Start tai-local (DIRECT mode, auto-detect Docker)
        run: |
          mkdir -p $RUNNER_TEMP/tai-local-data

          TAI_CREDENTIALS=$RUNNER_TEMP/tai-local-credentials \
          TAI_YAO_SERVER=http://127.0.0.1:${YAO_CI_HTTP_PORT} \
          TAI_DATA_DIR=$RUNNER_TEMP/tai-local-data \
          $RUNNER_TEMP/tai server \
            --grpc 127.0.0.1:${YAO_CI_TAI_LOCAL_GRPC_PORT} \
            --http 127.0.0.1:${YAO_CI_TAI_LOCAL_HTTP_PORT} \
            --vnc  127.0.0.1:${YAO_CI_TAI_LOCAL_VNC_PORT} \
            --docker 127.0.0.1:${YAO_CI_TAI_LOCAL_DOCKER_PORT} \
            --direct \
            --host-exec --host-exec-full-access \
            --log-level debug &

          echo $! > $RUNNER_TEMP/tai-local.pid
          echo "tai-local PID: $(cat $RUNNER_TEMP/tai-local.pid)"

          for i in $(seq 1 30); do
            if curl -sf http://127.0.0.1:${YAO_CI_TAI_LOCAL_HTTP_PORT}/healthz > /dev/null 2>&1; then
              echo "tai-local HTTP ready"
              break
            fi
            echo "Waiting for tai-local HTTP... ($i/30)"
            sleep 1
          done

      - name: Start tai-docker (TUNNEL mode, Docker API proxy)
        run: |
          mkdir -p $RUNNER_TEMP/tai-docker-data

          TAI_CREDENTIALS=$RUNNER_TEMP/tai-docker-credentials \
          TAI_YAO_SERVER=http://127.0.0.1:${YAO_CI_HTTP_PORT} \
          TAI_DATA_DIR=$RUNNER_TEMP/tai-docker-data \
          $RUNNER_TEMP/tai server \
            --grpc 127.0.0.1:${YAO_CI_TAI_DOCKER_GRPC_PORT} \
            --http 127.0.0.1:${YAO_CI_TAI_DOCKER_HTTP_PORT} \
            --vnc  127.0.0.1:${YAO_CI_TAI_DOCKER_VNC_PORT} \
            --docker 127.0.0.1:${YAO_CI_TAI_DOCKER_API_PORT} \
            --host-exec --host-exec-full-access \
            --log-level debug &

          echo $! > $RUNNER_TEMP/tai-docker.pid
          echo "tai-docker PID: $(cat $RUNNER_TEMP/tai-docker.pid)"

          for i in $(seq 1 30); do
            if curl -sf http://127.0.0.1:${YAO_CI_TAI_DOCKER_HTTP_PORT}/healthz > /dev/null 2>&1; then
              echo "tai-docker HTTP ready"
              break
            fi
            echo "Waiting for tai-docker HTTP... ($i/30)"
            sleep 1
          done

      - name: Start tai-k8s (TUNNEL mode, K8s API proxy)
        run: |
          mkdir -p $RUNNER_TEMP/tai-k8s-data

          TAI_CREDENTIALS=$RUNNER_TEMP/tai-k8s-credentials \
          TAI_YAO_SERVER=http://127.0.0.1:${YAO_CI_HTTP_PORT} \
          TAI_DATA_DIR=$RUNNER_TEMP/tai-k8s-data \
          TAI_K8S_UPSTREAM="tcp://127.0.0.1:${YAO_CI_K3D_API_PORT}" \
          TAI_KUBECONFIG=$RUNNER_TEMP/kubeconfig-tai.yml \
          $RUNNER_TEMP/tai server \
            --grpc 127.0.0.1:${YAO_CI_TAI_K8S_GRPC_PORT} \
            --http 127.0.0.1:${YAO_CI_TAI_K8S_HTTP_PORT} \
            --vnc  127.0.0.1:${YAO_CI_TAI_K8S_VNC_PORT} \
            --k8s  127.0.0.1:${YAO_CI_TAI_K8S_API_PORT} \
            --docker="" \
            --host-exec --host-exec-full-access \
            --log-level debug &

          echo $! > $RUNNER_TEMP/tai-k8s.pid
          echo "tai-k8s PID: $(cat $RUNNER_TEMP/tai-k8s.pid)"

          for i in $(seq 1 30); do
            if curl -sf http://127.0.0.1:${YAO_CI_TAI_K8S_HTTP_PORT}/healthz > /dev/null 2>&1; then
              echo "tai-k8s HTTP ready"
              break
            fi
            echo "Waiting for tai-k8s HTTP... ($i/30)"
            sleep 1
          done

      - name: Start tai-hostexec (TUNNEL mode, HostExec only, no runtime)
        run: |
          mkdir -p $RUNNER_TEMP/tai-hostexec-data

          TAI_CREDENTIALS=$RUNNER_TEMP/tai-hostexec-credentials \
          TAI_YAO_SERVER=http://127.0.0.1:${YAO_CI_HTTP_PORT} \
          TAI_DATA_DIR=$RUNNER_TEMP/tai-hostexec-data \
          $RUNNER_TEMP/tai server \
            --grpc 127.0.0.1:${YAO_CI_TAI_HOSTEXEC_GRPC_PORT} \
            --http 127.0.0.1:${YAO_CI_TAI_HOSTEXEC_HTTP_PORT} \
            --vnc  127.0.0.1:${YAO_CI_TAI_HOSTEXEC_VNC_PORT} \
            --docker="" \
            --host-exec --host-exec-full-access \
            --log-level debug &

          echo $! > $RUNNER_TEMP/tai-hostexec.pid
          echo "tai-hostexec PID: $(cat $RUNNER_TEMP/tai-hostexec.pid)"

          for i in $(seq 1 30); do
            if curl -sf http://127.0.0.1:${YAO_CI_TAI_HOSTEXEC_HTTP_PORT}/healthz > /dev/null 2>&1; then
              echo "tai-hostexec HTTP ready"
              break
            fi
            echo "Waiting for tai-hostexec HTTP... ($i/30)"
            sleep 1
          done

      # ==== Phase 7: Environment Verification (fail fast) ====
      - name: Verify Environment
        run: |
          echo "CI Environment v${CI_VERSION}"
          echo ""

          FAILED=0
          check() {
            local name=$1; shift
            if "$@" > /dev/null 2>&1; then
              echo "  [PASS] $name"
            else
              echo "  [FAIL] $name"
              FAILED=$((FAILED + 1))
            fi
          }

          echo "=== Environment Verification ==="

          # ── 1. Service Health ──
          echo ""
          echo "--- 1. Service Health ---"

          echo "[Yao]"
          check "Yao HTTP (/.well-known/yao)" curl -sf http://127.0.0.1:5099/.well-known/yao
          check "Yao gRPC port" nc -z 127.0.0.1 9099

          echo "[tai-local (DIRECT)]"
          check "tai-local process alive" kill -0 $(cat $RUNNER_TEMP/tai-local.pid 2>/dev/null || echo 0)
          check "tai-local HTTP (/healthz)" curl -sf http://127.0.0.1:${YAO_CI_TAI_LOCAL_HTTP_PORT}/healthz
          check "tai-local gRPC reachable (direct)" nc -z 127.0.0.1 ${YAO_CI_TAI_LOCAL_GRPC_PORT}

          echo "[tai-docker (TUNNEL)]"
          check "tai-docker process alive" kill -0 $(cat $RUNNER_TEMP/tai-docker.pid 2>/dev/null || echo 0)
          check "tai-docker HTTP (/healthz)" curl -sf http://127.0.0.1:${YAO_CI_TAI_DOCKER_HTTP_PORT}/healthz
          check "tai-docker gRPC listener" nc -z 127.0.0.1 ${YAO_CI_TAI_DOCKER_GRPC_PORT}

          echo "[tai-k8s (TUNNEL)]"
          check "tai-k8s process alive" kill -0 $(cat $RUNNER_TEMP/tai-k8s.pid 2>/dev/null || echo 0)
          check "tai-k8s HTTP (/healthz)" curl -sf http://127.0.0.1:${YAO_CI_TAI_K8S_HTTP_PORT}/healthz
          check "tai-k8s gRPC listener" nc -z 127.0.0.1 ${YAO_CI_TAI_K8S_GRPC_PORT}

          echo "[tai-hostexec (TUNNEL)]"
          check "tai-hostexec process alive" kill -0 $(cat $RUNNER_TEMP/tai-hostexec.pid 2>/dev/null || echo 0)
          check "tai-hostexec HTTP (/healthz)" curl -sf http://127.0.0.1:${YAO_CI_TAI_HOSTEXEC_HTTP_PORT}/healthz
          check "tai-hostexec gRPC listener" nc -z 127.0.0.1 ${YAO_CI_TAI_HOSTEXEC_GRPC_PORT}

          echo "[K8s (k3d via direct API)]"
          check "kubectl get nodes (k3d direct)" kubectl --kubeconfig=$RUNNER_TEMP/kubeconfig-tai.yml get nodes

          echo "[Data Stores]"
          MONGO_CID=$(docker ps -qf "ancestor=mongo:6.0" | head -1)
          check "MongoDB ping" docker exec "$MONGO_CID" mongosh --quiet \
            -u ${MONGO_TEST_USER} -p ${MONGO_TEST_PASS} --authenticationDatabase admin \
            --eval "db.runCommand({ping:1})"

          check "MySQL ping" docker exec mysql mysqladmin ping -h 127.0.0.1 \
            -u ${MYSQL_TEST_USER} -p${MYSQL_TEST_PASS}

          PG_CID=$(docker ps -qf "ancestor=postgres:14" | head -1)
          check "PostgreSQL ping" docker exec "$PG_CID" pg_isready -U ${PG_TEST_USER}

          check "Redis ping" docker exec redis redis-cli ping

          # ── 2. Network Topology ──
          echo ""
          echo "--- 2. Network Topology ---"

          BRIDGE_IP=${YAO_CI_BRIDGE_IP}

          echo "[Host network basics]"
          check "docker0 bridge exists" ip addr show docker0
          check "Bridge IP reachable (${BRIDGE_IP})" ping -c1 -W2 ${BRIDGE_IP}
          check "Docker socket accessible" test -S /var/run/docker.sock
          check "tai binary on runner" test -x $RUNNER_TEMP/tai

          echo "[Yao endpoints (all Tai instances need these)]"
          check "Yao HTTP :${YAO_CI_HTTP_PORT}" curl -sf http://127.0.0.1:${YAO_CI_HTTP_PORT}/.well-known/yao
          check "Yao gRPC :${YAO_CI_GRPC_PORT}" nc -z 127.0.0.1 ${YAO_CI_GRPC_PORT}

          echo "[DIRECT path: Yao → tai-local]"
          check "Yao→tai-local gRPC :${YAO_CI_TAI_LOCAL_GRPC_PORT}" nc -z 127.0.0.1 ${YAO_CI_TAI_LOCAL_GRPC_PORT}
          check "Yao→tai-local HTTP :${YAO_CI_TAI_LOCAL_HTTP_PORT}" curl -sf http://127.0.0.1:${YAO_CI_TAI_LOCAL_HTTP_PORT}/healthz
          check "tai-local Docker API proxy :${YAO_CI_TAI_LOCAL_DOCKER_PORT}" nc -z 127.0.0.1 ${YAO_CI_TAI_LOCAL_DOCKER_PORT}

          echo "[TUNNEL path: tai-docker → Yao gRPC (reverse tunnel)]"
          check "tai-docker→Yao gRPC :${YAO_CI_GRPC_PORT}" nc -z 127.0.0.1 ${YAO_CI_GRPC_PORT}
          check "tai-docker Docker API proxy :${YAO_CI_TAI_DOCKER_API_PORT}" nc -z 127.0.0.1 ${YAO_CI_TAI_DOCKER_API_PORT}
          check "Docker API via proxy" bash -c "curl -sf http://127.0.0.1:${YAO_CI_TAI_DOCKER_API_PORT}/version | jq -r .ApiVersion"

          echo "[TUNNEL path: tai-k8s → Yao gRPC (reverse tunnel)]"
          check "tai-k8s→Yao gRPC :${YAO_CI_GRPC_PORT}" nc -z 127.0.0.1 ${YAO_CI_GRPC_PORT}
          check "tai-k8s K8s API proxy :${YAO_CI_TAI_K8S_API_PORT}" nc -z 127.0.0.1 ${YAO_CI_TAI_K8S_API_PORT}
          sed "s|server: .*|server: https://127.0.0.1:${YAO_CI_TAI_K8S_API_PORT}|" $RUNNER_TEMP/kubeconfig-tai.yml \
            > $RUNNER_TEMP/kubeconfig-tai-proxy.yml
          check "K8s API via tai-k8s proxy (kubectl)" kubectl --kubeconfig=$RUNNER_TEMP/kubeconfig-tai-proxy.yml --insecure-skip-tls-verify get nodes

          echo "[TUNNEL path: tai-hostexec → Yao gRPC (reverse tunnel)]"
          check "tai-hostexec→Yao gRPC :${YAO_CI_GRPC_PORT}" nc -z 127.0.0.1 ${YAO_CI_GRPC_PORT}

          echo "[Data Store connectivity from runner]"
          check "MongoDB :27017" nc -z 127.0.0.1 27017
          check "Redis :6379" nc -z 127.0.0.1 6379
          check "MySQL :${MYSQL_TEST_PORT}" nc -z 127.0.0.1 ${MYSQL_TEST_PORT}
          check "PostgreSQL :${PG_TEST_PORT}" nc -z 127.0.0.1 ${PG_TEST_PORT}

          # ── 3. Connection Mode Verification ──
          echo ""
          echo "--- 3. Connection Modes ---"
          sleep 5

          echo "[Credentials (4 tokens)]"
          check "tai-local credentials exist" test -f $RUNNER_TEMP/tai-local-credentials
          check "tai-docker credentials exist" test -f $RUNNER_TEMP/tai-docker-credentials
          check "tai-k8s credentials exist" test -f $RUNNER_TEMP/tai-k8s-credentials
          check "tai-hostexec credentials exist" test -f $RUNNER_TEMP/tai-hostexec-credentials

          echo "[DIRECT: tai-local → Yao HTTP register → Yao dials tai-local gRPC]"
          echo "  tai-local registers via POST /tai-nodes/register"
          echo "  Yao dials back tai-local gRPC at 127.0.0.1:${YAO_CI_TAI_LOCAL_GRPC_PORT}"

          echo "[TUNNEL: tai-docker → Yao gRPC :${YAO_CI_GRPC_PORT} (Register + Forward)]"
          echo "  Sandbox connects Yao gRPC → Forward stream → tai-docker :${YAO_CI_TAI_DOCKER_GRPC_PORT}"

          echo "[TUNNEL: tai-k8s → Yao gRPC :${YAO_CI_GRPC_PORT} (Register + Forward)]"
          echo "  Sandbox connects Yao gRPC → Forward stream → tai-k8s :${YAO_CI_TAI_K8S_GRPC_PORT}"

          echo "[TUNNEL: tai-hostexec → Yao gRPC :${YAO_CI_GRPC_PORT} (Register + Forward)]"
          echo "  HostExec only, no container runtime"

          WELL_KNOWN=$(curl -sf http://127.0.0.1:5099/.well-known/yao 2>/dev/null || echo "{}")
          echo ""
          echo "  Yao .well-known/yao:"
          echo "$WELL_KNOWN" | jq . 2>/dev/null || echo "  $WELL_KNOWN"

          # ── 4. HostExec Readiness ──
          echo ""
          echo "--- 4. HostExec ---"

          echo "[HostExec gRPC ports (all 4 instances)]"
          check "HostExec tai-local (direct, auto-Docker)" nc -z 127.0.0.1 ${YAO_CI_TAI_LOCAL_GRPC_PORT}
          check "HostExec tai-docker (tunnel, Docker proxy)" nc -z 127.0.0.1 ${YAO_CI_TAI_DOCKER_GRPC_PORT}
          check "HostExec tai-k8s (tunnel, K8s proxy)" nc -z 127.0.0.1 ${YAO_CI_TAI_K8S_GRPC_PORT}
          check "HostExec tai-hostexec (tunnel, no runtime)" nc -z 127.0.0.1 ${YAO_CI_TAI_HOSTEXEC_GRPC_PORT}

          echo ""
          echo "=========================================="
          if [ $FAILED -gt 0 ]; then
            echo "::error::$FAILED verification check(s) FAILED"
            echo ""
            echo "=== Diagnostic Info ==="
            echo "--- Docker containers ---"
            docker ps -a
            echo ""
            echo "--- Processes (yao + tai) ---"
            ps aux | grep -E "yao|tai" | grep -v grep || true
            echo ""
            echo "--- Listening ports ---"
            ss -tlnp | grep -E "5099|9099|19100|19101|19102|19103|8099|8100|8101|8102|12375|12376|16443|16444" || true
            exit 1
          else
            echo "All verification checks PASSED"
          fi
