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>
This commit is contained in:
Apple
2026-02-09 08:46:46 -08:00
parent 134c044c21
commit ef3473db21
9473 changed files with 408933 additions and 2769877 deletions

View File

@@ -0,0 +1,491 @@
# 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