# Runbook: Sofiia Control Console **Service:** sofiia-console (NODA2 primary) **Port:** 8002 **UI:** http://localhost:8002/ --- ## 1. Endpoints | Method | Path | Auth | Description | |--------|------|------|-------------| | GET | `/` | — | Console UI (Chat + Ops + Nodes) | | GET | `/api/health` | — | Aggregated health (first node router) | | POST | `/api/chat/send` | X-API-Key* | Proxy to router `/v1/agents/sofiia/infer` | | GET | `/api/ops/actions` | — | List ops action ids | | POST | `/api/ops/run` | X-API-Key* | Run risk_dashboard / pressure_dashboard / backlog_generate_weekly / release_check | | GET | `/api/nodes/dashboard` | — | Per-node router health from `config/nodes_registry.yml` | \* If `SOFIIA_CONSOLE_API_KEY` is set, write endpoints require header `X-API-Key: `. --- ## 2. Environment variables | Variable | Description | Default | |----------|-------------|---------| | `ROUTER_URL` | Default router for health/chat when node not specified | `http://localhost:9102` | | `CONFIG_DIR` | Directory containing `nodes_registry.yml` (Docker: `/app/config`) | repo `config/` | | `NODES__ROUTER_URL` | Override router URL per node (e.g. `NODES_NODA1_ROUTER_URL`) | from registry | | `SUPERVISOR_API_KEY` | Sent to router on tool/infer calls (optional) | — | | `SOFIIA_CONSOLE_API_KEY` | Protects POST /api/chat/send and /api/ops/run | — (no auth if unset) | --- ## 3. Deploy (Docker, NODA2) ```bash cd /path/to/microdao-daarion docker compose -f docker-compose.node2-sofiia.yml up -d sofiia-console ``` Ensure `config/nodes_registry.yml` exists and lists `NODA1` / `NODA2` with correct `router_url`. Open http://localhost:8002/ --- ## 4. Run locally (no Docker) ```bash cd services/sofiia-console pip install -r requirements.txt export ROUTER_URL=http://localhost:8000 # or 9102 uvicorn app.main:app --host 0.0.0.0 --port 8002 ``` Then open http://localhost:8002/ --- ## 5. API key rotation (NODA2) Rotate both `SOFIIA_CONSOLE_API_KEY` and `SUPERVISOR_API_KEY` to one new value: ```bash cd /Users/apple/github-projects/microdao-daarion NEW_KEY="$(openssl rand -hex 24)" sed -i '' "s/^SOFIIA_CONSOLE_API_KEY=.*/SOFIIA_CONSOLE_API_KEY=${NEW_KEY}/" .env sed -i '' "s/^SUPERVISOR_API_KEY=.*/SUPERVISOR_API_KEY=${NEW_KEY}/" .env docker compose -f docker-compose.node2-sofiia.yml up -d sofiia-console router ``` Quick check in container env: ```bash docker exec sofiia-console sh -lc 'env | grep -E "^(ENV|SOFIIA_CONSOLE_API_KEY|SUPERVISOR_API_KEY)="' ``` --- ## 6. Ops API examples (with key) ```bash KEY="" ``` ```bash curl -sS -X POST http://localhost:8002/api/ops/run \ -H "X-API-Key: ${KEY}" -H "Content-Type: application/json" \ -d '{"action_id":"risk_dashboard","node_id":"NODA2","params":{}}' | jq . ``` ```bash curl -sS -X POST http://localhost:8002/api/ops/run \ -H "X-API-Key: ${KEY}" -H "Content-Type: application/json" \ -d '{"action_id":"pressure_dashboard","node_id":"NODA2","params":{}}' | jq . ``` ```bash curl -sS -X POST http://localhost:8002/api/ops/run \ -H "X-API-Key: ${KEY}" -H "Content-Type: application/json" \ -d '{"action_id":"release_check","node_id":"NODA2","params":{}}' | jq . ``` --- ## 7. Troubleshooting | Symptom | Cause | Fix | |---------|-------|-----| | Chat "Помилка мережі" | Router unreachable | Check ROUTER_URL and router container | | Ops run returns 502 | Router or tool error | Check router logs; verify RBAC for agent `sofiia` | | Nodes dashboard empty | No nodes in registry or CONFIG_DIR wrong | Check `config/nodes_registry.yml` and CONFIG_DIR mount | | 401 on POST /api/chat/send | API key required but missing/wrong | Set X-API-Key header to SOFIIA_CONSOLE_API_KEY or leave SOFIIA_CONSOLE_API_KEY unset | --- ## 8. Verification After deploy, run stack verifier (from repo root): ```bash export ROUTER_URL=http://localhost:8000 # or router:8000 inside Docker network python3 ops/scripts/verify_sofiia_stack.py ``` See `docs/opencode/sofiia_setup.md` for OpenCode integration and tool contract.