docs(platform): add policy configs, runbooks, ops scripts and platform documentation

Config policies (16 files): alert_routing, architecture_pressure, backlog,
cost_weights, data_governance, incident_escalation, incident_intelligence,
network_allowlist, nodes_registry, observability_sources, rbac_tools_matrix,
release_gate, risk_attribution, risk_policy, slo_policy, tool_limits, tools_rollout

Ops (22 files): Caddyfile, calendar compose, grafana voice dashboard,
deployments/incidents logs, runbooks for alerts/audit/backlog/incidents/sofiia/voice,
cron jobs, scripts (alert_triage, audit_cleanup, migrate_*, governance, schedule),
task_registry, voice alerts/ha/latency/policy

Docs (30+ files): HUMANIZED_STEPAN v2.7-v3 changelogs and runbooks,
NODA1/NODA2 status and setup, audit index and traces, backlog, incident,
supervisor, tools, voice, opencode, release, risk, aistalk, spacebot

Made-with: Cursor
This commit is contained in:
Apple
2026-03-03 07:14:53 -08:00
parent 129e4ea1fc
commit 67225a39fa
102 changed files with 20060 additions and 0 deletions

View File

@@ -0,0 +1,248 @@
# Sofiia UI vNext — Dependency Map (D)
> Generated: 2026-02-26 | Карта залежностей UI → Backend → DB → Events
---
## Легенда
| Символ | Значення |
|--------|----------|
| ✅ | Endpoint/Model реалізований |
| ⚠️ | Частково реалізований або за feature flag |
| ❌ | Відсутній, потрібна реалізація |
| 🔧 | Потрібне виправлення/доопрацювання |
| 📄 | Тільки документований |
---
## Таблиця 1: Chat & Voice
| UI Feature | Expected API/Event | Found? | Evidence | Action |
|-----------|-------------------|--------|----------|--------|
| Text chat | `POST /api/chat/send` | ✅ | `main.py` | — |
| Voice STT (WebM) | `POST /api/voice/stt` | ✅ | `main.py` → memory-service | — |
| Voice TTS | `POST /api/voice/tts` | ✅ | `main.py` (legacy + HA) | — |
| Voice Phase 2 stream | `POST /api/voice/chat/stream` | ✅ | `main.py` | — |
| Voice stop/abort | AbortController + `POST /api/voice/tts` cancel | ✅ | `index.html` JS | — |
| TTFA telemetry | `POST /api/telemetry/voice` | ✅ | `main.py` | — |
| Batch telemetry | `POST /api/telemetry/voice/batch` | ✅ | `main.py` | — |
| Degradation badge | `GET /api/voice/degradation_status` | ✅ | `main.py` | — |
| Remote voice badge | `X-Voice-Mode: remote` header | ✅ | `main.py` + `index.html` | — |
| Model selector UI | inline models list | ✅ | `index.html` (hardcoded) | 🔧 Should come from `/api/models` |
| Chat history restore | `GET /api/chat/history?session_id=` | ✅ | `docs_router.py` | — |
| Session persistence | localStorage `session_id` | ✅ | `index.html` | — |
| Memory status | `GET /api/memory/status` | ✅ | `main.py` | — |
---
## Таблиця 2: Projects
| UI Feature | Expected API/Event | Found? | Evidence | Action |
|-----------|-------------------|--------|----------|--------|
| Projects list | `GET /api/projects` | ✅ | `docs_router.py` | — |
| Create project | `POST /api/projects` | ✅ | `docs_router.py` | — |
| Get project | `GET /api/projects/{id}` | ✅ | `docs_router.py` | — |
| Update project | `PATCH /api/projects/{id}` | ✅ | `docs_router.py` | — |
| Delete project | `DELETE /api/projects/{id}` | ❌ | Not found | implement |
| Projects sidebar | `GET /api/projects` (on load) | ✅ | `index.html` `loadSidebarProjects()` | — |
| Project switcher | localStorage `project_id` | ✅ | `index.html` | — |
| **Board (Kanban)** | `GET /api/projects/{id}/tasks` | ❌ | Not found | implement or mock |
| **Tasks CRUD** | `/api/projects/{id}/tasks` | ❌ | Not found | implement |
| **Meetings** | `GET /api/projects/{id}/meetings` | ❌ | Not found | implement or mock |
| **Meeting create** | `POST /api/meetings` | ❌ | Not found | implement |
| **Meeting reminders** | NATS `meeting.reminder.*` | ❌ | Not found | Phase 2 |
| Project settings | `PATCH /api/projects/{id}` | ✅ | `docs_router.py` | — |
---
## Таблиця 3: Documents DB
| UI Feature | Expected API/Event | Found? | Evidence | Action |
|-----------|-------------------|--------|----------|--------|
| Upload file | `POST /api/files/upload` (multipart) | ✅ | `docs_router.py` | — |
| List documents | `GET /api/projects/{id}/documents` | ✅ | `docs_router.py` | — |
| Get document | `GET /api/projects/{id}/documents/{doc_id}` | ✅ | `docs_router.py` | — |
| Download file | `GET /api/files/{file_id}/download` | ✅ | `docs_router.py` | — |
| Search docs | `POST /api/projects/{id}/search` | ✅ | `docs_router.py` (SQL LIKE) | 🔧 Needs semantic search |
| Delete document | `DELETE /api/projects/{id}/documents/{doc_id}` | ❌ | Not found | implement |
| **Doc versioning** | `GET /docs/{id}/versions` | ❌ | Not found | implement (DDL needed) |
| **Restore version** | `POST /docs/{id}/restore` | ❌ | Not found | implement |
| **Doc diff** | `GET /docs/{id}/diff?from=&to=` | ❌ | Not found | Phase 2 |
| **Backlinks (entity_links)** | `POST /docs/{id}/links` | ❌ | Not found | implement |
| **"Index for AI" toggle** | `POST /docs/{id}/index` | ❌ | Not found (USE_EMBEDDINGS flag) | implement |
| **doc_index_state** | status tracking | ❌ | Not found | implement |
| **Wiki Markdown editor** | Frontend only | ❌ | Not in index.html | implement (Phase 2) |
| **Docs tree navigation** | Frontend only | ❌ | Not in index.html | implement (Phase 2) |
| Fabric OCR on upload | `POST /v1/capability/ocr` | ⚠️ | `USE_FABRIC_OCR=false` | enable flag |
| Embeddings on upload | Qdrant ingest via Router | ⚠️ | `USE_EMBEDDINGS=false` | enable flag |
| NATS event on upload | `attachment.created` | ❌ | Not published | add to upload handler |
---
## Таблиця 4: Sessions & Dialog Map
| UI Feature | Expected API/Event | Found? | Evidence | Action |
|-----------|-------------------|--------|----------|--------|
| Sessions list | `GET /api/sessions?project_id=` | ✅ | `docs_router.py` | — |
| Resume session | `GET /api/chat/history?session_id=` | ✅ | `docs_router.py` | — |
| Session title update | `PATCH /api/sessions/{id}/title` | ✅ | `docs_router.py` | — |
| Session fork | `POST /api/sessions/{id}/fork` | ✅ | `docs_router.py` | — |
| Dialog Map (tree) | `GET /api/sessions/{id}/map` | ✅ | `docs_router.py` | — |
| **Dialog Map (canvas)** | D3/Cytoscape rendering | ❌ | `<details>` tree only in UI | Phase 2 |
| **Project-level map** | `GET /api/projects/{id}/dialog-map` | ❌ | Not found | implement (Postgres needed) |
| **Node types** (task/doc/meeting) | NATS consumers | ❌ | Not found | Phase 2 |
| **Edge creation UI** | `POST /api/links` | ❌ | Not found | implement |
| **Pin important node** | `PATCH /api/sessions/{id}/pin/{msg_id}` | ❌ | Not found | implement |
| Real-time map updates | WS `dialog_map.updated` event | ❌ | Not found | implement |
| **Saved views** | `dialog_views` table | ❌ | Not found | implement |
---
## Таблиця 5: CTO Panel (Repo + Ops)
| UI Feature | Expected API/Event | Found? | Evidence | Action |
|-----------|-------------------|--------|----------|--------|
| Ops actions (risk/backlog/etc.) | `GET /api/ops/actions` | ✅ | `main.py` | — |
| Run ops action | `POST /api/ops/run` | ✅ | `main.py` + `ops.py` | — |
| Node health dashboard | `GET /api/nodes/dashboard` | ✅ | `main.py` | — |
| Node SSH status | `GET /api/nodes/ssh/status` | ✅ | `main.py` | — |
| Add node | `POST /api/nodes/add` | ✅ | `main.py` | — |
| Integrations status | `GET /api/integrations/status` | ✅ | `main.py` | — |
| **Repo changesets list** | `GET /api/repo/changesets` | ❌ | Not found | implement or mock |
| **Create changeset** | `POST /api/repo/changesets` | ❌ | Not found | implement |
| **Add patch** | `POST /api/repo/changesets/{id}/patches` | ❌ | Not found | implement |
| **Execution plan** | `POST /api/repo/changesets/{id}/plan` | ❌ | Not found | implement |
| **Create PR** | `POST /api/repo/changesets/{id}/pr` | ❌ | Not found | implement |
| **Run checks** | `POST /api/repo/pr/{id}/checks:run` | ❌ | Not found | implement |
| **Ops runs list** | `GET /api/ops/runs` | ❌ | Not found (only one-shot dispatch) | implement |
| **Ops run create** | `POST /api/ops/runs` (job-based) | ❌ | Not found | implement |
| **Ops run status** | `GET /api/ops/runs/{id}` | ❌ | Not found | implement |
| LangGraph runs | `POST /v1/graphs/{name}/runs` (Supervisor) | ✅ | `sofiia-supervisor` | 🔧 Not exposed via BFF |
| LangGraph status | `GET /v1/runs/{id}` | ✅ | `sofiia-supervisor` | 🔧 Not exposed via BFF |
| **repo_tool (read)** | via chat tools | ✅ | `tool_manager.py` | — |
| **pr_reviewer_tool** | via chat tools | ✅ | `tool_manager.py` | — |
---
## Таблиця 6: Database Model Dependency
| UI Screen | Required DB Table | Status | Storage | Action |
|-----------|------------------|--------|---------|--------|
| Chat history | `messages` | ✅ | SQLite | — |
| Projects | `projects` | ✅ | SQLite | — |
| Documents | `documents` | ✅ | SQLite | — |
| Sessions | `sessions` | ✅ | SQLite | — |
| Dialog Map (messages) | `messages.parent_msg_id` | ✅ | SQLite | — |
| **Dialog Map (graph)** | `dialog_nodes` + `dialog_edges` | ❌ | None | ADD TABLES |
| **Saved map views** | `dialog_views` | ❌ | None | ADD TABLE |
| **Doc versions** | `docs_versions` | ❌ | None | ADD TABLE |
| **Entity links** | `entity_links` | ❌ | None | ADD TABLE |
| **Tasks** | `tasks` | ❌ | None | ADD TABLE |
| **Meetings** | `meetings` | ❌ | None | ADD TABLE |
| **Repo changesets** | `repo_changesets` | ❌ | None | ADD TABLE |
| **Repo patches** | `repo_patches` | ❌ | None | ADD TABLE |
| **Pull requests** | `pull_requests` | ❌ | None | ADD TABLE |
| **Ops runs** | `ops_runs` | ❌ | None | ADD TABLE |
| Embeddings | Qdrant `sofiia_docs_*` | ⚠️ | Qdrant (disabled) | ENABLE FLAG |
| Long-term memory | Qdrant `sofiia_messages` | ✅ | Qdrant | — |
| Facts | Postgres `daarion_memory` | ✅ | Postgres | — |
---
## Таблиця 7: Real-time Events (WebSocket)
| Event | Direction | Status | Evidence |
|-------|-----------|--------|----------|
| `nodes.status` | Server → UI | ✅ | `main.py` WebSocket fan-out |
| `chat.reply` | Server → UI | ✅ | `main.py` |
| `voice.stt.result` | Server → UI | ✅ | `main.py` |
| `voice.tts.ready` | Server → UI | ✅ | `main.py` |
| `voice.stream.chunk` | Server → UI | ✅ | `main.py` |
| `ops.run.status` | Server → UI | ✅ | `main.py` |
| `error` | Server → UI | ✅ | `main.py` |
| `dialog_map.updated` | Server → UI | ❌ | Not found |
| `task.created` | Server → UI | ❌ | Not found |
| `doc.updated` | Server → UI | ❌ | Not found |
| `meeting.reminder` | Server → UI | ❌ | Not found |
| `repo.pr.status` | Server → UI | ❌ | Not found |
| `ops_run.completed` | Server → UI | ❌ | Not found |
---
## Таблиця 8: Security & Access Control
| Feature | Status | Evidence |
|---------|--------|----------|
| API key auth (console) | ✅ | `auth.py` |
| Strict auth (SSH/admin) | ✅ | `auth.py` strict mode |
| Rate limiting per endpoint | ✅ | `main.py` limiters |
| Upload sanitize (filename/mime) | ✅ | `docs_router.py` |
| Upload size limits (env-based) | ✅ | `UPLOAD_MAX_*_MB` env |
| RBAC tool allowlist | ✅ | `agent_tools_config.py` |
| `mode=confidential` check | ❌ | Not in BFF or Router |
| E2EE for docs | ❌ | Not implemented |
| Audit log for actions | ⚠️ | Partial (router audit.py) |
| 2-step Plan → Apply for risky ops | ❌ | Not implemented |
| CORS config | ⚠️ | Check `main.py` |
---
## Граф залежностей (логічний)
```
[index.html SPA]
┌───────────────┼───────────────┐
│ │ │
[chat+voice] [projects] [ops+nodes]
│ │ │
▼ ▼ ▼
/api/chat/send /api/projects /api/ops/run
/api/voice/* /api/files/* /api/nodes/*
/api/telemetry /api/sessions/* /api/integrations/*
│ │ │
▼ ▼ ▼
[Router BFF] [SQLite sofiia.db] [nodes health poll]
│ │ │
▼ ▼ ▼
[Router DAGI] [Memory Service] [SSH + node-worker]
/v1/agents/ /threads /events /caps
/v1/tools/ /memories /facts /voice/health
[LLM + Tools]
Grok / qwen3 / DeepSeek
+ 20+ tools (repo/pr/kb/etc.)
```
**Відсутні зв'язки (vNext):**
```
[index.html] → [Kanban Board] ←→ /api/projects/{id}/tasks
[index.html] → [Dialog Map canvas] ←→ /api/projects/{id}/dialog-map
[index.html] → [CTO Repo Panel] ←→ /api/repo/changesets
[index.html] → [CTO Ops Panel] ←→ /api/ops/runs (job-based)
[docs_router] → NATS attachment.created
[Supervisor] → BFF (not proxied)
```
---
## Next Actions for UI Team (12 days)
1. **Immediate (today)**: всі фічі chat/voice/projects/sessions/dialog-tree вже працюють — deploy і тестуйте через http://localhost:8002
2. **Quick wins (12 дні)**:
- `DELETE /api/projects/{id}` — 10 рядків коду
- `DELETE /api/projects/{id}/documents/{doc_id}` — 10 рядків
- BFF proxy до Supervisor: `POST /api/supervisor/runs``sofiia-supervisor:8080/v1/graphs/{name}/runs`
3. **Phase 2 UI (mock-first)**:
- Kanban board: спочатку in-memory tasks → `tasks` table
- Meetings: спочатку form → `meetings` table
- Dialog Map canvas: `<details>` tree → D3 tree → D3 force graph
4. **CTO Panel mock**: додати mock handlers для `/api/repo/changesets` і `/api/ops/runs`
5. **Увімкнути USE_EMBEDDINGS=true**: після перевірки що Qdrant доступний
6. **Expose Supervisor API через BFF**: один proxy endpoint в main.py
7. **NATS attachment.created**: додати до upload handler у docs_router.py
8. **`dialog_nodes/edges` tables**: DDL + API + WS events (найважливіше для vNext graph)
9. **`docs_versions` table**: ALTER + endpoint (для wiki history)
10. **Перевірити WebSocket**: всі voice/ops events реально приходять до UI