# NODA2 P0+P1 Validation Report **Date:** 2026-02-27 **Node:** NODA2 (MacBook Pro M4 Max) --- ## P0 — Vision Restore ### CHECK 1: /vision/models не порожній ```bash curl -s http://localhost:8890/vision/models | jq . ``` **Результат:** ```json {"models":[{"name":"llava-13b","type":"vision","status":"unloaded","size_gb":8.0}]} ``` **STATUS: ✅ PASS** — llava-13b зареєстрована як vision model --- ### CHECK 2: Vision inference end-to-end ```bash # Тест з мінімальним 1x1 PNG (base64) curl -s -X POST http://localhost:8890/vision \ -H 'Content-Type: application/json' \ -d '{"model":"llava-13b","prompt":"What do you see?","images":[""]}' ``` **Результат:** ```json { "success": true, "model": "llava-13b", "text": " I see a large block of solid green color...", "processing_time_ms": 3571, "images_count": 1 } ``` **STATUS: ✅ PASS** — inference виконується через Ollama (llava:13b), latency ~3.5s --- ### CHECK 3: Swapper health ```bash curl -s http://localhost:8890/health | jq .status ``` **Результат:** `"healthy"` **STATUS: ✅ PASS** --- ## P1 — Security ### CHECK 4: SSH key auth до NODA1 ```bash ssh -i secrets/noda1_id_ed25519 root@144.76.224.179 "echo 'key auth works'" ``` **Результат:** `SSH key PASS — no password` **STATUS: ✅ PASS** — ed25519 key авторизований на NODA1 --- ### CHECK 5: SSH password відсутній в env контейнера ```bash docker inspect sofiia-console --format '{{range .Config.Env}}{{println .}}{{end}}' | grep -i 'ssh_password' ``` **Очікуємо:** 0 рядків **STATUS:** ⚠️ PARTIAL — контейнер ще не перезапущений з новим compose. Після `docker compose up -d --no-deps sofiia-console` — PASS --- ### CHECK 6: SSH password відсутній в docker-compose (активний рядок) ```bash grep -E '^[^#]*SSH_PASSWORD' docker-compose.node2-sofiia.yml ``` **Результат:** 0 активних рядків (тільки коментарі) **STATUS: ✅ PASS** --- ### CHECK 7: SSH password відсутній в .env ```bash grep -E '^NODES_NODA1_SSH_PASSWORD=' .env ``` **Результат:** 0 рядків (тільки коментар з поясненням) **STATUS: ✅ PASS** --- ### CHECK 8: secrets/ в .gitignore ```bash grep 'noda1_id_ed25519' .gitignore ``` **Результат:** `secrets/noda1_id_ed25519` **STATUS: ✅ PASS** --- ## P1 — Router Config ### CHECK 9: router-config.node2.yml не містить 172.17.0.1 ```bash grep '172.17.0.1' services/router/router-config.node2.yml ``` **Результат:** 0 рядків (тільки коментар `# Version: 0.6.1 ... (no 172.17.0.1)`) **STATUS: ✅ PASS** --- ### CHECK 10: node2 compose монтує правильний config ```bash grep 'router-config' docker-compose.node2-sofiia.yml ``` **Результат:** `./services/router/router-config.node2.yml:/app/router-config.yml:ro` **STATUS: ✅ PASS** --- ## P1 — Port Binding ### CHECK 11: Внутрішні порти на 127.0.0.1 ```bash grep -E '(9102|8890|8002):' docker-compose.node2-sofiia.yml ``` **Результат:** ``` - "127.0.0.1:9102:8000" - "127.0.0.1:8890:8890" - "127.0.0.1:8002:8002" ``` **STATUS: ✅ PASS** --- ## Підсумок | Check | Тест | Статус | |-------|------|--------| | P0-1 | /vision/models не порожній | ✅ PASS | | P0-2 | Vision inference (llava-13b, ~3.5s) | ✅ PASS | | P0-3 | Swapper healthy | ✅ PASS | | P1-4 | SSH key auth до NODA1 | ✅ PASS | | P1-5 | SSH_PASSWORD не в env контейнера | ⚠️ PARTIAL (потрібен restart sofiia-console) | | P1-6 | SSH_PASSWORD не в compose (активний рядок) | ✅ PASS | | P1-7 | SSH_PASSWORD не в .env | ✅ PASS | | P1-8 | secrets/ в .gitignore | ✅ PASS | | P1-9 | router-config.node2.yml без 172.17.0.1 | ✅ PASS | | P1-10 | compose монтує node2 router config | ✅ PASS | | P1-11 | Внутрішні порти на 127.0.0.1 | ✅ PASS | **Підсумок: 10/11 PASS, 1 PARTIAL (потрібен `docker compose up -d`)** --- ## Залишилось виконати ```bash # 1. Перезапустити sofiia-console з новим compose (прибере password env) docker compose -f docker-compose.node2-sofiia.yml up -d --no-deps sofiia-console # 2. Перезапустити router з node2-specific config docker compose -f docker-compose.node2-sofiia.yml up -d --no-deps router # 3. Верифікація після restart docker inspect sofiia-console --format '{{range .Config.Env}}{{println .}}{{end}}' | grep -i 'ssh' # Очікуємо: NODES_NODA1_SSH_PRIVATE_KEY=/run/secrets/noda1_ssh_key (і НЕ SSH_PASSWORD) ```