# 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"
