# Sofiia CTO Agent — State of Implementation (B) > Generated: 2026-02-26 | Legend: ✅ Implemented | ⚠️ Partial | 📄 Documented Only | ❌ Not Found --- ## 1. Identity & System Prompt | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | Sofiia identity (AGENTS.md) | ✅ Implemented | `AGENTS.md` — CTO-агент, NODA1/2/3, capabilities | — | | Telegram system prompt | ✅ Implemented | `gateway-bot/sofiia_prompt.txt` (138KB) | — | | Control Console system prompt | ✅ Implemented | `services/sofiia-console/app/main.py` lines 138–177 | — | | Voice turn prompt suffix | ✅ Implemented | `main.py` `SOFIIA_VOICE_PROMPT_SUFFIX` — max 2 sentences, no markdown | — | | Agent ID consistency | ⚠️ Partial | `"sofiia"` у production, `"l"` у node2-конфігурації та тестах | ⚠️ Confusion risk | | NODA3 integration | 📄 Documented Only | `AGENTS.md` описує NODA3 (IP, GPU, models), але немає compose/config | 🔴 Blocking | --- ## 2. Control Console (BFF) | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | FastAPI BFF основа | ✅ Implemented | `sofiia-console/app/main.py` v0.3.0, 1800 рядків | — | | Chat: Ollama/Router/GLM/Grok | ✅ Implemented | `/api/chat/send`, providers: ollama, router, glm, grok | — | | Chat: history (client-side) | ✅ Implemented | `body.history[-12:]` передається клієнтом | — | | Chat: session persist (SQLite) | ✅ Implemented | `_do_save_memory` → `db.save_message`, `db.upsert_session` | — | | Chat: session restore on page reload | ✅ Implemented | `GET /api/chat/history`, localStorage session_id | — | | Ops: risk/pressure/backlog/release | ✅ Implemented | `/api/ops/run` + `ops.py` dispatcher | — | | Ops: Notion actions | ✅ Implemented | notion_status/create_task/create_page/create_database | — | | Hub: integrations status | ✅ Implemented | `/api/integrations/status` — Router, Memory, OpenWebUI, Pieces, OpenCode, Notion | — | | Nodes: dashboard | ✅ Implemented | `/api/nodes/dashboard` з caching, multi-node poll | — | | Nodes: SSH status | ✅ Implemented | `/api/nodes/ssh/status` (strict auth) | — | | Nodes: add node | ✅ Implemented | `/api/nodes/add` | — | | Nodes: remove node | ❌ Not Found | Тільки add, без delete | ⚠️ Minor gap | | Memory: status | ✅ Implemented | `/api/memory/status` | — | | Memory: context | ✅ Implemented | `/api/memory/context` | — | | WebSocket event bus | ✅ Implemented | `/ws/events` — nodes.status, chat.reply, voice.*, ops.run | — | | Rate limiting | ✅ Implemented | per-endpoint limiters: 30/min chat, 15/min stream, 30/min TTS | — | | API key auth | ✅ Implemented | `auth.py` + strict mode | — | --- ## 3. Voice Layer | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | STT proxy | ✅ Implemented | `POST /api/voice/stt` → memory-service | — | | TTS proxy | ✅ Implemented | `POST /api/voice/tts` (legacy + HA path) | — | | Voice streaming Phase 2 | ✅ Implemented | `POST /api/voice/chat/stream` — split → first TTS | — | | Voice policy (voice_fast_uk/quality_uk) | ✅ Implemented | `router-config.yml`, `test_voice_policy.py` 23/23 | — | | Voice guardrails (2 sentences) | ✅ Implemented | `SOFIIA_VOICE_PROMPT_SUFFIX`, `sanitize_for_voice()` | — | | `` stripping | ✅ Implemented | `voice_utils.py` + Router `_clean_think_blocks` | — | | Degradation state machine | ✅ Implemented | `_VoiceDegradationSM` (ok/degraded_tts/degraded_llm/fast_lock/emergency) | — | | TTFA telemetry | ✅ Implemented | `POST /api/telemetry/voice` + Prometheus metrics | — | | Voice HA (multi-node routing) | ✅ Implemented | `VOICE_HA_ENABLED` flag, Router `/v1/capability/voice_*` | — | | Remote voice badge | ✅ Implemented | `X-Voice-Mode: remote` header → `🌐 noda1` badge | — | | Voice canary | ✅ Implemented | `ops/scripts/voice_canary.py` (preflight + runtime mode) | — | | Grafana voice dashboard | ✅ Implemented | `ops/grafana_voice_dashboard.json` | — | | Voice alerts (Prometheus) | ✅ Implemented | `ops/voice_alerts.yml` (6 rules) | — | | SLO definitions | ✅ Implemented | `config/slo_policy.yml` voice_fast_uk / voice_quality_uk | — | | Rate limit / DoS guard | ✅ Implemented | semaphore, per-IP limiter, `rest_chunks ≤ 8` cap | — | --- ## 4. Projects, Documents, Sessions | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | Projects CRUD | ✅ Implemented | `docs_router.py`: GET/POST/PATCH `/api/projects` | — | | Documents CRUD | ✅ Implemented | upload, list, get, keyword search | — | | File upload (multipart) | ✅ Implemented | `POST /api/files/upload` — sha256, mime detect, size limit | — | | Text extraction (PDF/DOCX/TXT) | ✅ Implemented | `_extract_text_simple()` у docs_router | — | | Sessions persistence | ✅ Implemented | `upsert_session`, `save_message`, SQLite `sofiia.db` | — | | Chat history restore | ✅ Implemented | `GET /api/chat/history?session_id=...` | — | | Dialog Map (tree) | ✅ Implemented | `GET /api/sessions/{sid}/map` → nodes/edges | — | | Dialog Map (canvas/D3) | ❌ Not Found | Поточний — `
` collapsible tree тільки | Phase 2 | | Session fork | ✅ Implemented | `POST /api/sessions/{sid}/fork` | — | | Projects sidebar (chat UI) | ✅ Implemented | `#sidebarProjectList` у `index.html` | — | | Projects section (full UI) | ✅ Implemented | `#section-projects` з tabs: docs, sessions, map | — | | Fabric OCR для uploaded images | ⚠️ Feature Flag Off | `USE_FABRIC_OCR=false` за замовч. | Low risk | | Qdrant embeddings для docs | ⚠️ Feature Flag Off | `USE_EMBEDDINGS=false` за замовч. | Low risk | | Docs versions (history) | ❌ Not Found | `docs_versions` таблиця відсутня | 🔴 vNext gap | | Docs backlinks (entity_links) | ❌ Not Found | `docs_links`/`entity_links` таблиця відсутня | 🔴 vNext gap | | `doc_index_state` table | ❌ Not Found | Відсутня | 🔴 vNext gap | | Semantic search (Meilisearch) | ❌ Not Found | Тільки SQL LIKE keyword search | 📄 ADR describes it | --- ## 5. CTO-specific Capabilities (Repo/Ops) | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | `repo_tool` (read-only) | ✅ Implemented | `tool_manager.py` — tree/read/search/metadata | — | | `pr_reviewer_tool` | ✅ Implemented | `tool_manager.py` — blocking_only/full_review | — | | `contract_tool` (OpenAPI) | ✅ Implemented | `tool_manager.py` — lint_openapi/diff_openapi/generate_client_stub | — | | `oncall_tool` | ✅ Implemented | services_list/health/runbook_search/incident_log | — | | `observability_tool` | ✅ Implemented | Prometheus/Loki/Tempo queries | — | | `config_linter_tool` | ✅ Implemented | Secrets detection, policy violations | — | | `threatmodel_tool` | ✅ Implemented | STRIDE-based threat modeling | — | | `job_orchestrator_tool` | ✅ Implemented | smoke/drift/backup/deploy tasks | — | | `kb_tool` | ✅ Implemented | ADR/docs search | — | | `drift_analyzer_tool` | ✅ Implemented | Infrastructure drift detection | — | | `risk_engine_tool` | ✅ Implemented | Risk scoring | — | | `architecture_pressure_tool` | ✅ Implemented | Architecture health analysis | — | | `backlog_tool` | ✅ Implemented | Backlog generation/management | — | | `dependency_scanner_tool` | ✅ Implemented | Dependency security scan | — | | `incident_intelligence_tool` | ✅ Implemented | Incident correlation | — | | `cost_analyzer_tool` | ✅ Implemented | Cost analysis | — | | `notion_tool` | ✅ Implemented | Notion pages/tasks/databases | — | | **`repo_changesets`** (CTO workflow) | ❌ Not Found | Тільки описано в vNext design | 🔴 Blocking | | **`ops_runs` API** | ❌ Not Found | Тільки `ops.py` dispatcher (не як job system) | 🔴 Blocking | | **`pull_requests` API** | ❌ Not Found | PR Review tool є, але PR object як артефакт — немає | 🔴 vNext gap | | **`entity_links`** | ❌ Not Found | Concept described, not implemented | 🔴 vNext gap | | Direct NODA3 integration | ❌ Not Found | Описано в AGENTS.md, відсутній docker-compose/router config | 🔴 | --- ## 6. Supervisor (LangGraph) | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | Alert triage graph | ✅ Implemented | `alert_triage_graph.py` + tests | — | | Incident triage graph | ✅ Implemented | `incident_triage_graph.py` + tests | — | | Postmortem draft graph | ✅ Implemented | `postmortem_draft_graph.py` + tests | — | | Release check graph | ✅ Implemented | `release_check_graph.py` + tests | — | | Supervisor API | ✅ Implemented | `/v1/graphs/{name}/runs` | — | | **CTO workflow graph** (intent→plan→execute) | ❌ Not Found | Описано в vNext design, немає реалізації | 🔴 vNext gap | | **Repo changeset graph** | ❌ Not Found | Тільки в дизайн-доці | 🔴 vNext gap | --- ## 7. Memory System | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | Short-term memory (threads/events) | ✅ Implemented | Memory Service `/threads`, `/events` | — | | Long-term memory (Qdrant) | ✅ Implemented | `/memories` + semantic search | — | | Facts store | ✅ Implemented | `/facts/upsert`, `/facts/{key}` | — | | Agent memory (Postgres + Neo4j) | ✅ Implemented | `/agents/{id}/memory` | — | | Rolling summaries | ✅ Implemented | `/threads/{id}/summarize` | — | | Neo4j graph memory | ✅ Infrastructure Ready | docker-compose.memory-node2.yml | Не тестований | | **Personal namespace** | ⚠️ Partial | ADR описує `user_{id}_*` collections, реалізація через `user_id` param | — | | **Team/DAO namespace** | 📄 Documented Only | ADR, не реалізовано в code | 🔴 vNext gap | | **E2EE (confidential docs)** | 📄 Documented Only | ADR + PRIVACY_GATE.md, не реалізовано | 🔴 vNext gap | --- ## 8. Infrastructure | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | NODA2 Docker stack | ✅ Implemented | `docker-compose.node2-sofiia.yml` | — | | NODA1 health + SSH | ✅ Implemented | nodes.py + SSH key auth | — | | Prometheus metrics | ✅ Implemented | fabric_metrics.py (router + node-worker), voice metrics | — | | NATS subjects | ✅ Implemented | Fabric node.{id}.*.request subjects | — | | Voice HA semaphores | ✅ Implemented | node-worker separate voice semaphores | — | | sofiia-data volume | ✅ Implemented | docker-compose.node2-sofiia.yml sofiia-data:/app/data | — | | Postgres для sofiia docs | ⚠️ SQLite Only | Phase 1: SQLite у sofiia-console, Postgres для Memory Service | Phase 2 needed | | S3/MinIO storage | ❌ Not Found | ADR описує, upload зараз у volume | 🔴 Phase 2 | | Meilisearch | ❌ Not Found | ADR описує для search, не розгорнутий | 🔴 vNext | | Control Plane service | ❌ Not Found | ADR 1.1-1.3, reference у security audit | 🔴 vNext | --- ## 9. Security | Feature | Status | Evidence | Risk | |---------|--------|----------|------| | RBAC per agent | ✅ Implemented | `rbac_tools_matrix.yml` agent_cto (39 permissions) | — | | Tool allowlist per agent | ✅ Implemented | `agent_tools_config.py` AGENT_SPECIALIZED_TOOLS["sofiia"] | — | | API key auth | ✅ Implemented | `auth.py` — console + strict modes | — | | Upload sanitization (filename/mime) | ✅ Implemented | `_safe_filename()`, `_detect_mime()` у docs_router | — | | Rate limiting | ✅ Implemented | per-endpoint + semaphore + `rest_chunks ≤ 8` | — | | **E2EE (confidential)** | ❌ Not Found | Privacy Gate описаний в ADR, не реалізований | 🔴 | | **2-step approval для dangerous actions** | ❌ Not Found | ADR описує Plan → Apply flow | 🔴 vNext | | Audit log (append-only) | ⚠️ Partial | audit.py у agromatrix crew, `audit.{service}.{action}` NATS — частково | 🔴 | --- ## Next Actions for UI Team (1–2 days) 1. **Зверніть увагу**: `repo_changesets`, `ops_runs`, `entity_links` — **не існують**. UI CTO panel потребує mock endpoints 2. **Quick win**: `docs_versions` таблиця — 30хв роботи (ALTER TABLE + endpoint у docs_router.py) 3. **Quick win**: увімкнути `USE_EMBEDDINGS=true` в docker-compose для реального vector search 4. **Перевірити** соfiia agent_id у тестах: `"l"` vs `"sofiia"` — потрібна нормалізація 5. **Postgres migration**: коли sofiia-console готова до Postgres, потрібен `DATABASE_URL` env + аналогічний `init_db()` 6. **E2EE**: перед вмиканням confidential docs — треба спроєктувати ключі (client-side only) 7. **Dialog Map Phase 2**: canvas rendering (D3/Cytoscape) — `
` tree є, але не масштабується 8. **Meilisearch**: поки `LIKE` search, але коли кількість docs зросте — потрібен реальний search index 9. **NODA3**: додати до `nodes_registry.yml` і `docker-compose.node2-sofiia.yml` (якщо NODA3 реально доступна) 10. **CTO workflow graph**: перший крок — alert_triage граф вже є, на його основі зробити `cto_intent_graph`