Files
microdao-daarion/docs/ADR_ARCHITECTURE_VNEXT.md
Apple ef3473db21 snapshot: NODE1 production state 2026-02-09
Complete snapshot of /opt/microdao-daarion/ from NODE1 (144.76.224.179).
This represents the actual running production code that has diverged
significantly from the previous main branch.

Key changes from old main:
- Gateway (http_api.py): expanded from ~40KB to 164KB with full agent support
- Router: new /v1/agents/{id}/infer endpoint with vision + DeepSeek routing
- Behavior Policy: SOWA v2.2 (3-level: FULL/ACK/SILENT)
- Agent Registry: config/agent_registry.yml as single source of truth
- 13 agents configured (was 3)
- Memory service integration
- CrewAI teams and roles

Excluded from snapshot: venv/, .env, data/, backups, .tgz archives

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 08:46:46 -08:00

492 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR: Improved microdao-daarion Architecture vNext
**Дата:** 2026-01-19
**Статус:** Прийнято (Phased Rollout)
**Версія:** 1.0
---
## Контекст
Поточний стек (Gateway → Router → Swapper → Memory Layer + NATS) працює для MVP, але має обмеження при масштабуванні на багато нод. Потрібно:
1. Легше масштабувати на багато нод
2. Не "розмити" межі сервісів
3. Зробити приватність/аудит/квоти системними, а не точковими
---
## Рішення: Control Plane + Data Plane Architecture
### Загальна схема
```
┌─────────────────────────────────────────────────────────────────┐
│ CONTROL PLANE │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ RBAC/PDP │ │ Config │ │ Observability │ │
│ │ Service │ │ Registry │ │ + Audit │ │
│ └─────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
[Policy Cache + Config Sync]
┌─────────────────────────────────────────────────────────────────┐
│ DATA PLANE │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ BFF │ │ Ingest │ │ DAGI │ │ Swapper │ │
│ │ Gateway │───▶│ Service │ │ Router │───▶│ Runtime │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ └───────────────┴───────────────┴───────────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ NATS Cluster │ │
│ │ (Events + Jobs) │ │
│ └─────────┬─────────┘ │
│ │ │
│ ┌──────────────────────┼──────────────────────┐ │
│ │ │ │ │
│ ┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐ │
│ │ Memory │ │ CrewAI │ │ Parser │ │
│ │ Service │ │ Workers │ │ Pipeline │ │
│ └─────────┘ └───────────┘ └───────────┘ │
│ │ │
│ ┌────▼────────────────────────────────────────┐ │
│ │ Postgres │ Qdrant │ Neo4j │ Redis │ S3 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
---
## 1. Control Plane (повільніша, керує правилами)
### 1.1 RBAC/PDP Service
- Policy Decision Point — окремий сервіс
- Кешований на Data Plane рівні
- Обробляє: entitlements, scopes, modes, quotas
### 1.2 Config Registry
- Версії системних промптів
- Routing rules (версійовані)
- Quotas per user/team/agent
- Feature flags
- Allowlists/blocklists
### 1.3 Observability + Audit
- Незмінні журнали (append-only)
- Prometheus метрики
- Grafana dashboards
- Alerting (PagerDuty/Slack)
---
## 2. Data Plane (шлях запиту, низька латентність)
### 2.1 BFF Gateway (замість монолітного Gateway)
**Відповідальність:**
- Auth, sessions, throttling
- Webhook signature verification
- Request validation & shaping
- Rate limiting (per user/IP/team)
- TLS termination
**НЕ відповідальність:**
- Обробка мультимедіа (винесено в Ingest)
- Бізнес-логіка (винесено в Router)
### 2.2 Ingest Service (НОВИЙ)
**Відповідальність:**
- Прийом файлів (фото/відео/аудіо/документи)
- Virus scan / size limits
- Upload до Object Storage (S3/MinIO)
- Публікація події `attachment.created`
**Переваги:**
- Gateway не блокується важкими операціями
- Формалізований потік: файл → подія → обробка
- Outbox pattern для надійності
### 2.3 DAGI Router (stateless)
**Залишається:**
- Routing rules (версійовані з Config Registry)
- Tool registry (дозволені інструменти)
- Policy checks (mode/confidential, scopes, budgets)
- Privacy Gate (mode-aware middleware)
**Виноситься:**
- Довгі workflow → CrewAI Workers
- Стани задач → NATS + Memory
- Проміжні артефакти → Object Storage
**Статус:** Повністю stateless, горизонтально масштабується
### 2.4 Swapper Runtime
**Відповідальність:**
- LLM inference (local/cloud)
- Vision processing
- OCR
- STT/TTS
- Image generation
- Lazy loading/unloading моделей
**Статус:** Capability runtime, не має бізнес-логіки
### 2.5 Memory Service
**Відповідальність:**
- CRUD для всіх data stores
- Інкапсуляція Postgres/Qdrant/Neo4j/Redis
- Без бізнес-логіки продукту
**3 рівні пам'яті:**
| Scope | Qdrant | Neo4j | Postgres |
|-------|--------|-------|----------|
| **Personal** | `user_{id}_*` collections | `:User` nodes + ACL | `user_facts`, `user_sessions` |
| **Team/DAO** | `team_{id}_*` collections | `:Team`, `:Project` nodes | `team_facts`, `team_quotas` |
| **Public** | `public_*` collections | `:Public` nodes | `indexed_content` |
**Правило:** Індексація plaintext дозволена лише для `scope=public + indexed=true`. Для confidential — тільки шифротекст/метадані.
---
## 3. Async Workers (через NATS)
### 3.1 CrewAI Workers
**Позиціонування:** Workflow/Job runtime, НЕ в лінії запиту
**Принципи:**
- Бере задачі з NATS JetStream
- Ідемпотентність (idempotency key)
- Пише результат у Memory Service
- Повертає статус подією
**Синхронно (в лінії запиту):** Тільки короткі задачі (LLM answer ≤ N секунд)
**Асинхронно (job):** Все інше
### 3.2 Parser Pipeline
**Тригер:** `attachment.created` подія
**Потік:**
```
attachment.created → Parser Worker →
→ extraction/chunking →
→ артефакти для RAG →
→ attachment.parsed подія
```
### 3.3 RAG Indexer
**Тригер:** `attachment.parsed` або `content.updated`
**Потік:**
```
content.updated → Embeddings →
→ Qdrant upsert →
→ content.indexed подія
```
---
## 4. Privacy Gate (обов'язковий middleware)
### Правило
Якщо `mode=confidential`:
- Router передає в агентний шар тільки **узагальнений контекст / embedding / features**
- Або контент тільки з **явної згоди**
- Логи без контенту (тільки метрики)
### Реалізація
```python
class PrivacyGate:
def check(self, request: Request) -> GateResult:
if request.mode == "confidential":
if not request.user_consent:
return GateResult(
allow=False,
transform=self.sanitize_context,
log_content=False
)
return GateResult(allow=True, log_content=True)
def sanitize_context(self, context: str) -> str:
# Повертає тільки узагальнений summary
return summarize(context, max_tokens=100)
```
---
## 5. NATS Standards
### 5.1 Subject Naming Convention
```
# Messages
message.created.{channel_id}
message.edited.{channel_id}
message.deleted.{channel_id}
# Attachments
attachment.created.{type} # type: image/video/audio/document
attachment.parsed.{type}
attachment.indexed.{type}
# Agent Operations
agent.run.requested.{agent_id}
agent.run.started.{agent_id}
agent.run.completed.{agent_id}
agent.run.failed.{agent_id}
# Handoff (orchestration)
agent.handoff.requested.{from}.{to}
agent.handoff.completed.{from}.{to}
# Quota
quota.consumed.{user_id}
quota.blocked.{user_id}
quota.reset.{user_id}
# Audit (append-only)
audit.{service}.{action}
# Ops
ops.health.{service}
ops.alert.{severity}
```
### 5.2 Outbox Pattern
```sql
CREATE TABLE outbox (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
aggregate_type VARCHAR(255) NOT NULL,
aggregate_id VARCHAR(255) NOT NULL,
event_type VARCHAR(255) NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
published_at TIMESTAMPTZ,
status VARCHAR(20) DEFAULT 'pending'
);
CREATE INDEX idx_outbox_pending ON outbox(status, created_at)
WHERE status = 'pending';
```
### 5.3 Dead Letter Queue (DLQ)
- Всі невдалі обробки йдуть у DLQ
- Retry policy: exponential backoff
- Alert після N retries
---
## 6. Observability: AgentOps Layer
### 6.1 Per-Agent Metrics
```yaml
agent_latency_seconds{agent_id, operation}
agent_tokens_in_total{agent_id, model}
agent_tokens_out_total{agent_id, model}
agent_error_rate{agent_id, error_type}
agent_tool_calls_total{agent_id, tool}
agent_budget_consumed{agent_id, user_id}
```
### 6.2 Per-Channel Metrics
```yaml
channel_rag_hit_rate{channel_id}
channel_index_lag_seconds{channel_id}
channel_ws_fanout_latency_seconds{channel_id}
```
### 6.3 Per-Node Metrics
```yaml
node_gpu_utilization{node_id, gpu_id}
node_vram_used_bytes{node_id, gpu_id}
node_queue_lag_seconds{node_id, queue}
node_nats_stream_lag{node_id, stream}
```
### 6.4 Auto-Routing Rules
```yaml
# Якщо GPU зайнятий > 80%, переключити на API модель
routing_rules:
- condition: node_gpu_utilization > 0.8
action: route_to_cloud_llm
- condition: agent_error_rate > 0.1
action: fallback_to_backup_agent
```
---
## 7. Multi-Node Topology
### 7.1 Global Entry
```
gateway.daarion.city (TLS/WAF)
[Load Balancer]
┌────┴────┐
│ │
Node1 Node2 ...
```
### 7.2 Per-Node Stack
```
┌─────────────────────────────────────┐
│ NODE 1 │
│ ┌───────────────────────────────┐ │
│ │ Local Edge Ingress │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ Local DAGI Router │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ Local Swapper (GPU) │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ NATS Leafnode │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ Redis Cache │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
```
### 7.3 Data Layer
| Component | Topology |
|-----------|----------|
| **Postgres** | Primary + Read Replicas (або per-DAO sharding пізніше) |
| **Qdrant** | Replication/Sharding |
| **Neo4j** | Central + Read Replicas (або domain separation) |
| **NATS** | Supercluster / Leafnodes |
---
## 8. Phased Rollout Plan
### Phase 1: Foundation (2-3 тижні)
**Пріоритет:** Не ламати MVP
- [ ] Створити Config Registry (версії промптів, routing rules)
- [ ] Додати Privacy Gate middleware в Router
- [ ] Стандартизувати NATS subjects
- [ ] Додати Outbox pattern в Memory Service
- [ ] AgentOps метрики (базові)
### Phase 2: Separation (3-4 тижні)
**Пріоритет:** Розділити responsibilities
- [ ] Виділити Ingest Service з Gateway
- [ ] Зробити Router повністю stateless
- [ ] Винести CrewAI в async workers
- [ ] Додати Parser Pipeline
- [ ] Audit append-only stream
### Phase 3: Scale (4-6 тижнів)
**Пріоритет:** Multi-node готовність
- [ ] NATS leafnodes topology
- [ ] Per-node stack template (k3s)
- [ ] Auto-routing rules (GPU/load based)
- [ ] DLQ та retry policies
- [ ] Full observability dashboard
### Phase 4: Production (ongoing)
- [ ] Load testing
- [ ] Chaos engineering
- [ ] DR (disaster recovery) runbooks
- [ ] SLA monitoring
---
## 9. Migration Notes
### 9.1 Backward Compatibility
- Gateway endpoints залишаються незмінними
- Внутрішня структура змінюється поступово
- Feature flags для поступового rollout
### 9.2 Breaking Changes
| Change | Impact | Mitigation |
|--------|--------|------------|
| Ingest Service | File upload latency | Async processing + webhooks |
| Stateless Router | Session state | Move to NATS/Redis |
| Async CrewAI | Response time | Progress events + SSE |
---
## 10. Files to Create/Modify
### Нові сервіси:
- `/services/ingest/` — Ingest Service
- `/services/config-registry/` — Config Registry
- `/services/audit/` — Audit Service
### Модифікації:
- `/gateway-bot/` → BFF Gateway (спростити)
- `/services/router/` → Stateless + Privacy Gate
- `/services/swapper/` → Capability Runtime (без змін)
- `/services/memory-service/` → + Outbox pattern
### Документація:
- `/docs/ADR_ARCHITECTURE_VNEXT.md` — цей документ
- `/docs/NATS_SUBJECTS.md` — стандарти subjects
- `/docs/PRIVACY_GATE.md` — правила приватності
---
## Альтернативи (відхилені)
1. **Монолітний підхід** — не масштабується
2. **Full microservices одразу** — занадто складно для команди
3. **Serverless (Lambda/Cloud Functions)** — cold start, vendor lock-in
---
## Наслідки
### Позитивні:
- Горизонтальне масштабування
- Чіткі межі сервісів
- Системна приватність та аудит
- Multi-node ready
### Негативні:
- Більше сервісів = більше operational complexity
- Потрібен час на міграцію
- Потрібен моніторинг distributed system
---
**Версія:** 1.0
**Автор:** Architecture Team
**Останнє оновлення:** 2026-01-19