# NODA2 Audit Report **Дата:** 2026-02-27 **Нода:** MacBook Pro M4 Max (Apple Silicon) **Аудитор:** Sofiia (Cursor session) --- ## Executive Summary NODA2 — це MacBook Pro M4 Max з 64GB RAM, на якому розгорнутий повний dev-стек DAARION.city. NATS leafnode успішно підключений до NODA1 (rtt=58ms). Основний стек (router, gateway, memory, swapper, qdrant) здоровий. Критичний gap: vision pipeline зламаний (`/vision/models` порожній, qwen3-vl:8b не встановлена). Sofiia керує NODA1 через SSH root password — SECURITY risk. node-ops-worker не реалізований. --- ## Part A — Runtime Inventory ### Hardware | Параметр | Значення | |----------|---------| | CPU | Apple M4 Max | | RAM | 64 GB (unified) | | Storage free | 634 GB / 1.8 TB | | OS | macOS 26.3 (Darwin arm64) | ### Docker Containers (12) | Container | Port | Status | |-----------|------|--------| | `dagi-router-node2` | 9102→8000 | ✅ healthy | | `dagi-gateway-node2` | 9300 | ✅ healthy (14 agents) | | `dagi-nats-node2` | 4222, 8222 | ✅ running (leafnode→NODA1) | | `dagi-memory-service-node2` | 8000 | ✅ healthy | | `dagi-qdrant-node2` | 6333-6334 | ✅ healthy | | `swapper-service-node2` | 8890 | ✅ healthy | | `dagi-postgres-node2` | 5433→5432 | ✅ healthy | | `dagi-neo4j-node2` | 7474, 7687 | ✅ healthy | | `sofiia-console` | 8002 | ⚠️ running (no healthcheck) | | `open-webui` | 8080 | ✅ healthy (v0.7.2) | | `dagi-postgres` | 5432 | ✅ healthy | | `dagi-redis` | 6379 | ✅ healthy | ### Non-Docker Services | Process | Port | Description | |---------|------|-------------| | `ollama` | 11434 | System daemon, 11 models | | `llama-server` | 11435 | llama.cpp server, Qwen3.5-35B-A3B | | `gitea` | 3000 | Self-hosted Git (v1.25.3) | | `spacebot` | 19898 | Telegram bot → sofiia-console BFF | | `opencode` | 3456 | OpenCode.app AI coding tool | ### NATS Leafnode Status ``` NODA2 (spoke) ──58ms──> NODA1 144.76.224.179:7422 (hub) Cross-node pub/sub: PASS (node.test.hello confirmed) ``` ### Qdrant Collections | Collection | Points | |-----------|--------| | sofiia_messages | 2 | | sofiia_docs | 0 | | sofiia_memory_items | 0 | | sofiia_user_context | 0 | | memories | 0 | | messages | 0 | --- ## Part B — Sofiia Agent Inventory ### Registry Entry ```yaml agent_id: sofiia display_name: Sophia class: top_level canonical_role: Chief AI Architect & Technical Sovereign visibility: private telegram: enabled (whitelist) prompt_file: gateway-bot/sofiia_prompt.txt (1579 lines) ``` ### Runtime - **Gateway**: `dagi-gateway-node2:9300` — зареєстрована з 13 іншими агентами - **Router**: `dagi-router-node2:9102` — `NODE_ID=NODA2`, `nats_connected=true` - **Console UI**: `http://localhost:8002` — Python process, HTML UI - `NODES_NODA1_ROUTER_URL=http://144.76.224.179:9102` - `NODES_NODA2_ROUTER_URL=http://router:8000` - `ROUTER_URL=http://router:8000` - ⚠️ `NODES_NODA1_SSH_PASSWORD=[secret present]` — SECURITY RISK - **Spacebot**: Telegram → `sofiia-console BFF (http://localhost:8002/api)` ### Node Control (current state) - **Механізм**: SSH root з паролем (в env sofiia-console) - **Що є**: `NODES_NODA1_SSH_PASSWORD` в Docker env - **Чого немає**: NATS node-ops-worker, allowlist команд, audit log --- ## Part C — Models Audit ### Ollama (port 11434) | Model | Type | Size | Status | |-------|------|------|--------| | `qwen3.5:35b-a3b` | LLM (MoE) | 9.3 GB | available (14.8B active) | | `qwen3:14b` | LLM | 9.3 GB | available | | `gemma3:latest` | LLM | 3.3 GB | available | | `glm-4.7-flash:32k` | LLM | 19 GB | available (32k context) | | `glm-4.7-flash:q4_K_M` | LLM | 19 GB | available | | **`llava:13b`** | **Vision** | **8.0 GB** | **available (LLaVA+CLIP)** | | `mistral-nemo:12b` | LLM | 7.1 GB | available | | `deepseek-coder:33b` | Code | 18 GB | available | | `deepseek-r1:70b` | LLM (Reasoning) | 42 GB | available | | `starcoder2:3b` | Code | 1.7 GB | available | | `phi3:latest` | LLM | 2.2 GB | available | | `gpt-oss:latest` | LLM | 13 GB | available | | ~~qwen3-vl:8b~~ | Vision | ~8 GB | **NOT INSTALLED** | ### llama-server (port 11435, llama.cpp) | Model | Type | Note | |-------|------|------| | `Qwen3.5-35B-A3B-Q4_K_M.gguf` | LLM | Same as Ollama qwen3.5:35b-a3b — DUPLICATE | ### Swapper (port 8890) | Endpoint | Status | |----------|--------| | `/health` | `{"status":"healthy","active_model":"qwen3-14b"}` | | `/models` | 200 (9 configured, 1 loaded) | | `/vision/models` | ⚠️ 200 but **empty list** | | `/stt/models` | 200 | | `/tts/models` | 200 | **Swapper models configured** (з swapper_config_node2.yaml): - Loaded: `qwen3:14b` - Unloaded: gpt-oss, phi3, qwen3.5:35b-a3b, glm-4.7-flash, deepseek-coder:33b, deepseek-r1:70b - ⚠️ NOT installed: `gemma2:27b`, `qwen2.5-coder:32b` ### Capabilities Summary ```yaml vision_models: [llava:13b] # legacy, available; qwen3-vl:8b recommended text_models: [qwen3.5:35b-a3b, qwen3:14b, glm-4.7-flash, gemma3, mistral-nemo, deepseek-r1:70b] code_models: [deepseek-coder:33b, starcoder2:3b] embedding_models: [unknown - check memory-service] stt_models: [whisper via swapper - details TBD] tts_models: [xtts/coqui via swapper - details TBD] ``` --- ## Part D — Findings ### P0 — Негайно | ID | Issue | |----|-------| | FAIL-01 | **Vision pipeline broken**: `/vision/models=[]`, qwen3-vl:8b not installed, llava:13b not in swapper config | ### P1 — Цього тижня | ID | Issue | |----|-------| | FAIL-02 | **node-ops-worker не реалізований** — Sofiia керує NODA1 через SSH root password | | FAIL-03 | **router-config.yml**: `172.17.0.1:11434` (Linux bridge) — потрібно `host.docker.internal:11434` | | SEC-01 | **SSH password в Docker env** sofiia-console | | SEC-03 | **NODA2 порти на 0.0.0.0** без firewall | ### P2 — Наступний спринт | ID | Issue | |----|-------| | PART-03 | `llama-server:11435` дублює Ollama — waste of memory | | PART-04 | Qdrant memory collections empty — memory/RAG не використовується | | PART-02 | Swapper config: gemma2:27b, qwen2.5-coder:32b — не встановлені | | - | Cross-node vision routing NODA1→NODA2 через NATS не реалізований | --- ## Рекомендований Action Plan ### Крок 1 (P0): Виправити vision ```bash # На NODA2: ollama pull qwen3-vl:8b # Додати до swapper_config_node2.yaml секцію vision: # vision_models: # - name: qwen3-vl:8b # type: vision # priority: high ``` ### Крок 2 (P1): Виправити router-config.yml ```bash sed -i '' 's|http://172.17.0.1:11434|http://host.docker.internal:11434|g' router-config.yml docker restart dagi-router-node2 ``` ### Крок 3 (P1): Реалізувати node-ops-worker ``` services/node_ops_worker/ main.py — NATS subscriber allowlist.py — whitelist команд metrics.py — ops_requests_total, ops_errors_total Subjects: node.noda1.ops.request / node.noda2.ops.request ``` ### Крок 4 (P1): Видалити SSH password з env ```bash # Видалити NODES_NODA1_SSH_PASSWORD з docker-compose.node2.yml # Додати SSH key-based auth або перейти на NATS node-ops ``` --- ## Канонічні Endpoints NODA2 (для NODA1 routing) | Service | Internal | Via NATS | |---------|----------|----------| | Ollama LLM | `http://host.docker.internal:11434` | `node.noda2.llm.request` (TBD) | | Ollama Vision | `http://host.docker.internal:11434` | `node.noda2.vision.request` (TBD) | | Swapper | `http://host.docker.internal:8890` | `node.noda2.swapper.request` (TBD) | | Router | `http://host.docker.internal:9102` | via NATS messaging |