# 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
