- ops/audit_node2_20260227.md: readable report (hardware, containers, models, Sofiia, findings) - ops/audit_node2_20260227.json: structured machine-readable inventory - ops/audit_node2_findings.yml: 10 PASS + 5 PARTIAL + 3 FAIL + 3 SECURITY gaps - ops/node2_capabilities.yml: router-ready capabilities (vision/text/code/stt/tts models) Key findings: P0: vision pipeline broken (/vision/models=empty, qwen3-vl:8b not installed) P1: node-ops-worker missing, SSH root password in sofiia-console env P1: router-config.yml uses 172.17.0.1 (Linux bridge) not host.docker.internal Made-with: Cursor
152 lines
8.3 KiB
YAML
152 lines
8.3 KiB
YAML
# NODA2 Audit Findings
|
|
# Date: 2026-02-27
|
|
# Auditor: Sofiia (Cursor session)
|
|
|
|
# ── PASS (що працює) ──────────────────────────────────────────────────────
|
|
pass:
|
|
- id: PASS-01
|
|
title: "NATS leafnode NODA2→NODA1 connected"
|
|
detail: "spoke=true, rtt=58ms, cross-node pub/sub tested and working"
|
|
|
|
- id: PASS-02
|
|
title: "Docker stack healthy"
|
|
detail: "All 12 containers running. 10 have healthcheck PASS. NATS no healthcheck docker-level (compensated by leafnode check)."
|
|
|
|
- id: PASS-03
|
|
title: "Router NODA2 operational"
|
|
detail: "nats_connected=true, NODE_ID=NODA2, 14 agents registered, mounts local router-config.yml"
|
|
|
|
- id: PASS-04
|
|
title: "Ollama 11 models available"
|
|
detail: "qwen3.5:35b-a3b (primary), qwen3:14b, llava:13b (vision), deepseek-r1:70b, deepseek-coder:33b, glm-4.7-flash, gemma3, mistral-nemo, starcoder2, phi3, gpt-oss"
|
|
|
|
- id: PASS-05
|
|
title: "Swapper healthy, active_model=qwen3-14b"
|
|
detail: "/health=healthy, /models=200, /vision/models=200, /stt/models=200, /tts/models=200"
|
|
|
|
- id: PASS-06
|
|
title: "Sofiia agent registered in gateway (14 agents)"
|
|
detail: "sofiia present in agent_registry.yml, 1579-line prompt, class=top_level, telegram enabled"
|
|
|
|
- id: PASS-07
|
|
title: "Memory + Qdrant operational"
|
|
detail: "6 collections present (sofiia_messages:2 points, others empty). sofiia_docs ready for indexing."
|
|
|
|
- id: PASS-08
|
|
title: "Sofiia Console UI running"
|
|
detail: "http://localhost:8002, Python process, connects to NODA1 router (http://144.76.224.179:9102) and NODA2 router"
|
|
|
|
- id: PASS-09
|
|
title: "Gitea (self-hosted Git) running"
|
|
detail: "http://localhost:3000, version 1.25.3. Internal code repo."
|
|
|
|
- id: PASS-10
|
|
title: "Spacebot + OpenCode running"
|
|
detail: "Spacebot uses sofiia-console BFF. OpenCode.app active. Both integrated with NODA2 stack."
|
|
|
|
# ── PARTIAL (частково) ────────────────────────────────────────────────────
|
|
partial:
|
|
- id: PART-01
|
|
title: "Vision capability: llava:13b available but outdated"
|
|
detail: "llava:13b in Ollama (vision_capable=true via CLIP). But swapper /vision/models returns empty - llava not added to swapper_config_node2.yaml. qwen3-vl:8b not installed."
|
|
action: "Install qwen3-vl:8b OR add llava:13b to swapper vision config"
|
|
|
|
- id: PART-02
|
|
title: "Router LLM profiles use 172.17.0.1 (Docker bridge IP, Linux-style)"
|
|
detail: "router-config.yml has base_url: http://172.17.0.1:11434 for all profiles. On macOS Docker, this is host.docker.internal. Works because Ollama binds 127.0.0.1 and Docker on Mac uses host.docker.internal correctly — BUT 172.17.0.1 may not work in all network configurations."
|
|
action: "Replace 172.17.0.1:11434 with host.docker.internal:11434 in router-config.yml for NODA2"
|
|
|
|
- id: PART-03
|
|
title: "llama-server:11435 duplicates Ollama (same Qwen3.5-35B model)"
|
|
detail: "Wastes memory. Two instances of same model. No routing config points to 11435."
|
|
action: "Either remove llama-server or add it as dedicated profile in router-config.yml with specific purpose"
|
|
|
|
- id: PART-04
|
|
title: "Qdrant memory collections mostly empty"
|
|
detail: "sofiia_messages:2, all others 0. Memory not being used/indexed actively."
|
|
action: "Enable memory indexing in memory-service config or start ingesting docs"
|
|
|
|
- id: PART-05
|
|
title: "Sofiia Console not fully integrated"
|
|
detail: "UI serves HTML on :8002. Has NODES_NODA1_ROUTER_URL configured. But no node-ops-worker for NATS-based control. SSH password in env."
|
|
action: "Implement node-ops-worker (see FAIL-02)"
|
|
|
|
# ── FAIL (зламано) ────────────────────────────────────────────────────────
|
|
fail:
|
|
- id: FAIL-01
|
|
title: "Vision pipeline broken end-to-end"
|
|
detail: "Swapper /vision/models=[] (empty). No vision model configured in swapper_config_node2.yaml. Router has no vision profile pointing to NODA2. Photo requests would fail silently or go to NODA1."
|
|
priority: P0
|
|
action: |
|
|
1. Add llava:13b to swapper_config_node2.yaml vision section
|
|
2. OR install: ollama pull qwen3-vl:8b and add to swapper config
|
|
3. Add NODA2 vision profile to router-config.yml
|
|
|
|
- id: FAIL-02
|
|
title: "Node-ops-worker not implemented"
|
|
detail: "Sofiia has no NATS-based node control. Only mechanism is SSH root (password in env = SECURITY RISK). No subjects: node.noda1.ops.request, node.noda2.ops.request"
|
|
priority: P1
|
|
action: |
|
|
1. Implement services/node_ops_worker/ (Python NATS subscriber)
|
|
2. Allowlist: docker ps/logs/restart, health curl, tail logs
|
|
3. Deploy to both NODA1 and NODA2
|
|
4. Remove NODES_NODA1_SSH_PASSWORD from env
|
|
|
|
- id: FAIL-03
|
|
title: "NODA2 router-config.yml profiles use 172.17.0.1 (Linux Docker bridge)"
|
|
detail: "On macOS, Docker containers use host.docker.internal for host access. 172.17.0.1 may or may not resolve depending on Docker version."
|
|
priority: P1
|
|
action: "Replace 172.17.0.1:11434 → host.docker.internal:11434 in router-config.yml"
|
|
|
|
# ── SECURITY risks ────────────────────────────────────────────────────────
|
|
security:
|
|
- id: SEC-01
|
|
title: "SSH root password in sofiia-console container env"
|
|
detail: "NODES_NODA1_SSH_PASSWORD=[secret present] in sofiia-console Docker env. Any process inside the container can read it."
|
|
severity: HIGH
|
|
priority: P1
|
|
action: |
|
|
1. Remove NODES_NODA1_SSH_PASSWORD from docker env
|
|
2. Use SSH key-based auth instead (mount private key as secret)
|
|
3. Better: implement NATS node-ops-worker (FAIL-02) to eliminate SSH dependency
|
|
|
|
- id: SEC-02
|
|
title: "DATABASE_URL with plaintext password in router env"
|
|
detail: "DATABASE_URL=postgresql://daarion:XXXXX@... in router container. Acceptable for local dev, risk if container is compromised."
|
|
severity: MEDIUM
|
|
priority: P2
|
|
action: "Use Docker secrets or env file with restricted permissions"
|
|
|
|
- id: SEC-03
|
|
title: "NODA2 external IP (145.224.111.147) — ports exposed"
|
|
detail: "All Docker ports bound to 0.0.0.0. If NODA2 has external IP, ports 9300 (gateway), 9102 (router), 8890 (swapper), 8000 (memory) are publicly accessible."
|
|
severity: HIGH
|
|
priority: P1
|
|
action: "Add firewall rules (macOS pfctl or router-level) to restrict inbound to trusted IPs only"
|
|
|
|
# ── Summary ───────────────────────────────────────────────────────────────
|
|
summary:
|
|
current_state:
|
|
- "NODA2 = MacBook Pro M4 Max, 64GB RAM, macOS 26.3"
|
|
- "12 Docker containers running, 10 healthy"
|
|
- "NATS leafnode connected to NODA1 (rtt=58ms, cross-node pub/sub PASS)"
|
|
- "Ollama: 11 models, primary=qwen3.5:35b-a3b + qwen3:14b. Vision=llava:13b (legacy)"
|
|
- "llama-server:11435 running Qwen3.5-35B-A3B via llama.cpp (duplicates Ollama)"
|
|
- "Swapper active_model=qwen3-14b, vision/models=EMPTY (gap)"
|
|
- "Sofiia: agent_registry entry, 1579-line prompt, gateway registered"
|
|
- "Sofiia Console UI on :8002, connects to NODA1+NODA2 routers"
|
|
- "Spacebot (Telegram) → sofiia-console BFF → NODA2 stack"
|
|
- "Memory: 6 Qdrant collections (mostly empty), Neo4j running"
|
|
|
|
gaps:
|
|
- "P0: Vision pipeline broken — swapper /vision/models=empty, qwen3-vl:8b not installed"
|
|
- "P1: node-ops-worker not implemented — Sofiia controls NODA1 via SSH root password (SECURITY)"
|
|
- "P1: router-config.yml on NODA2 uses 172.17.0.1 (should be host.docker.internal)"
|
|
- "P1: NODA2 ports exposed on 0.0.0.0 without firewall — security risk"
|
|
- "P1: SSH root password in sofiia-console env"
|
|
- "P2: llama-server:11435 duplicates Ollama — memory waste"
|
|
- "P2: Qdrant memory collections empty — memory/RAG not being used"
|
|
- "P2: No cross-node vision routing (NODA1 can't send vision tasks to NODA2 via NATS yet)"
|
|
- "P2: Swapper config missing llava:13b in vision section"
|
|
- "P2: swapper_config_node2.yaml references gemma2:27b and qwen2.5-coder:32b — NOT installed"
|