feat(mvp): DAGI Integration Fix - gov_level, DAIS, nodes table

TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201

A) Agents Layer:
- A1: Added gov_level to API and UI (list + profile)
- A2: Added dais_identity_id to API and UI
- A3: Added home_microdao_id/name/slug for ownership display

B) MicroDAO Layer:
- B1/B2: Already implemented (agents, rooms, citizens, district badge)

C) Nodes Layer:
- C1: Node Dashboard already implemented
- C2: Created nodes table migration with owner_microdao_id
- C3: INSERT NODE1/NODE2 with dao_daarion ownership

D) Backend Fixes:
- D1: Extended /api/agents/* with DAIS/governance fields
- D2/D3: Already implemented

Files changed:
- services/city-service/repo_city.py
- services/city-service/models_city.py
- services/city-service/routes_city.py
- services/city-service/migrations.py
- apps/web/src/lib/types/agents.ts
- apps/web/src/lib/agent-dashboard.ts
- apps/web/src/app/agents/page.tsx
- apps/web/src/components/agent-dashboard/AgentSummaryCard.tsx

Reports:
- docs/debug/mvp_dagi_integration_fix_report_20251201.md
- docs/tasks/TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201.md
This commit is contained in:
Apple
2025-11-30 08:45:07 -08:00
parent a23deae3c4
commit 644edd3f30
22 changed files with 1227 additions and 82 deletions

View File

@@ -1,9 +1,9 @@
'use client';
import Link from 'next/link';
import { Bot, Users, Building2, Server, ExternalLink } from 'lucide-react';
import { Bot, Users, Building2, Server, ExternalLink, Shield } from 'lucide-react';
import { useAgentList } from '@/hooks/useAgents';
import { AgentSummary } from '@/lib/types/agents';
import { AgentSummary, getGovLevelBadge } from '@/lib/types/agents';
// Kind emoji mapping
const kindEmoji: Record<string, string> = {
@@ -33,6 +33,7 @@ function AgentCard({ agent }: { agent: AgentSummary }) {
const statusColor = isOnline ? 'text-emerald-400' : 'text-white/40';
const emoji = kindEmoji[agent.kind] || '🤖';
const nodeBadge = getNodeBadge(agent.home_node?.id);
const govBadge = getGovLevelBadge(agent.gov_level);
return (
<Link
@@ -82,7 +83,7 @@ function AgentCard({ agent }: { agent: AgentSummary }) {
{/* Footer */}
<div className="pt-4 border-t border-white/10 flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="flex items-center gap-2 flex-wrap">
<span className={`flex items-center gap-1.5 text-xs ${statusColor}`}>
<span
className={`w-2 h-2 rounded-full ${
@@ -94,6 +95,13 @@ function AgentCard({ agent }: { agent: AgentSummary }) {
<span className={`px-2 py-0.5 rounded text-[10px] font-medium ${nodeBadge.color}`}>
{nodeBadge.label}
</span>
{/* Gov Level Badge (A1) */}
{agent.gov_level && (
<span className={`px-2 py-0.5 rounded text-[10px] font-medium flex items-center gap-1 ${govBadge.color}`}>
<Shield className="w-3 h-3" />
{govBadge.label}
</span>
)}
{agent.is_public && (
<span className="px-2 py-0.5 rounded text-[10px] font-medium bg-cyan-500/20 text-cyan-400">
Public

View File

@@ -1,7 +1,10 @@
'use client';
import Link from 'next/link';
import { AgentProfile, AgentRuntime, getAgentKindIcon, getAgentStatusColor } from '@/lib/agent-dashboard';
import { StatusBadge } from '@/components/node-dashboard';
import { getGovLevelBadge } from '@/lib/types/agents';
import { Shield, Fingerprint, Building2 } from 'lucide-react';
interface AgentSummaryCardProps {
profile: AgentProfile;
@@ -10,6 +13,7 @@ interface AgentSummaryCardProps {
export function AgentSummaryCard({ profile, runtime }: AgentSummaryCardProps) {
const kindIcon = getAgentKindIcon(profile.kind);
const govBadge = getGovLevelBadge(profile.gov_level);
return (
<div className="bg-white/5 backdrop-blur-md rounded-2xl border border-white/10 p-6">
@@ -60,6 +64,20 @@ export function AgentSummaryCard({ profile, runtime }: AgentSummaryCardProps) {
>
{kindIcon} {profile.kind}
</span>
{/* Gov Level Badge (A1) */}
{profile.gov_level && (
<span className={`px-2 py-1 rounded-md text-sm font-medium flex items-center gap-1 ${govBadge.color}`}>
<Shield className="w-3 h-3" />
{govBadge.label}
</span>
)}
{/* DAIS Identity (A2) */}
{profile.dais_identity_id && (
<span className="px-2 py-1 bg-violet-500/20 text-violet-400 rounded-md text-sm flex items-center gap-1">
<Fingerprint className="w-3 h-3" />
{profile.dais_identity_id}
</span>
)}
{profile.roles.map(role => (
<span
key={role}
@@ -72,6 +90,22 @@ export function AgentSummaryCard({ profile, runtime }: AgentSummaryCardProps) {
</div>
</div>
{/* Home MicroDAO (A3) */}
{(profile.home_microdao_id || profile.primary_microdao_id) && (
<div className="mt-4 pt-4 border-t border-white/10">
<div className="flex items-center gap-2 text-sm">
<Building2 className="w-4 h-4 text-cyan-400" />
<span className="text-white/50">Belongs to:</span>
<Link
href={`/microdao/${profile.home_microdao_slug || profile.primary_microdao_slug}`}
className="text-cyan-400 hover:text-cyan-300 font-medium"
>
{profile.home_microdao_name || profile.primary_microdao_name}
</Link>
</div>
</div>
)}
{/* Runtime info */}
{runtime && (
<div className="mt-4 pt-4 border-t border-white/10 flex items-center gap-4">

View File

@@ -91,6 +91,13 @@ export interface AgentProfile {
primary_microdao_id?: string;
primary_microdao_name?: string;
primary_microdao_slug?: string;
// Governance & DAIS (A1, A2)
gov_level?: string | null;
dais_identity_id?: string | null;
// Home MicroDAO (A3)
home_microdao_id?: string | null;
home_microdao_name?: string | null;
home_microdao_slug?: string | null;
roles: string[];
tags: string[];
dais: DAIS;

View File

@@ -71,6 +71,10 @@ export interface AgentSummary {
node_label?: string | null;
home_node?: HomeNode | null;
// Governance & DAIS (A1, A2)
gov_level?: string | null; // personal, core_team, orchestrator, district_lead, city_governance
dais_identity_id?: string | null; // DAIS identity reference
// Visibility & roles
visibility_scope: VisibilityScope;
is_listed_in_directory: boolean;
@@ -78,10 +82,13 @@ export interface AgentSummary {
is_public: boolean;
is_orchestrator: boolean;
// MicroDAO
// MicroDAO (A3)
primary_microdao_id?: string | null;
primary_microdao_name?: string | null;
primary_microdao_slug?: string | null;
home_microdao_id?: string | null; // Owner microDAO
home_microdao_name?: string | null;
home_microdao_slug?: string | null;
district?: string | null;
microdaos: MicrodaoBadge[];
microdao_memberships: AgentMicrodaoMembership[];
@@ -187,3 +194,22 @@ export function getVisibilityScopeLabel(scope: VisibilityScope): string {
default: return scope;
}
}
/**
* Gov level configuration (A1)
*/
export const GOV_LEVEL_CONFIG: Record<string, { label: string; color: string; emoji: string }> = {
city_governance: { label: 'City Governance', color: 'bg-amber-500/20 text-amber-400', emoji: '👑' },
district_lead: { label: 'District Lead', color: 'bg-purple-500/20 text-purple-400', emoji: '🏛️' },
orchestrator: { label: 'Orchestrator', color: 'bg-cyan-500/20 text-cyan-400', emoji: '🎭' },
core_team: { label: 'Core Team', color: 'bg-blue-500/20 text-blue-400', emoji: '⚡' },
personal: { label: 'Personal', color: 'bg-gray-500/20 text-gray-400', emoji: '👤' },
};
/**
* Get gov level badge info
*/
export function getGovLevelBadge(govLevel?: string | null): { label: string; color: string; emoji: string } {
if (!govLevel) return { label: 'Unknown', color: 'bg-gray-500/20 text-gray-400', emoji: '❓' };
return GOV_LEVEL_CONFIG[govLevel] || { label: govLevel, color: 'bg-gray-500/20 text-gray-400', emoji: '❓' };
}

View File

@@ -0,0 +1,133 @@
# MVP DAGI Integration Fix Report — 2025-12-01
## Summary
Виконано всі 11 пунктів з `TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201.md`.
Ланцюг **"документи → код → деплой → UI"** тепер замкнутий для agents, microDAO та nodes.
---
## A) Agents Layer
### ✅ A1. Gov-level у UI
- **Backend**: Додано `gov_level` до SQL-запиту в `repo_city.py` (line ~389)
- **Models**: Додано `gov_level: Optional[str]` до `AgentSummary` в `models_city.py`
- **Routes**: Передається в API відповідь в `routes_city.py`
- **Frontend Types**: Додано `gov_level` до `AgentSummary` в `apps/web/src/lib/types/agents.ts`
- **Frontend UI**:
- `/agents` — показує gov-level badge з іконкою Shield
- `/agents/[agentId]` — показує gov-level у AgentSummaryCard
- **Helper**: Створено `getGovLevelBadge()` та `GOV_LEVEL_CONFIG` для відображення рівнів
### ✅ A2. DAIS ID у UI
- **Backend**: Додано `dais_identity_id` до SQL-запиту
- **Models**: Додано `dais_identity_id: Optional[str]` до `AgentSummary`
- **Frontend Types**: Додано `dais_identity_id` до `AgentSummary`
- **Frontend UI**: Показується в AgentSummaryCard з іконкою Fingerprint
### ✅ A3. MicroDAO membership
- **Backend**: Додано `home_microdao_id`, `home_microdao_name`, `home_microdao_slug` до SQL
- **Models**: Додано відповідні поля до `AgentSummary`
- **Frontend**:
- AgentSummaryCard показує "Belongs to: <microDAO>" з посиланням
- AgentMicrodaoMembershipCard вже існував і працює
---
## B) MicroDAO Layer
### ✅ B1. MicroDAO Dashboard
Вже реалізовано в `/microdao/[slug]/page.tsx`:
- Список агентів з ролями та core-бейджами
- Список кімнат (MicrodaoRoomsSection)
- Список громадян (public_citizens)
- Child microDAOs
### ✅ B2. District-level badge
Вже реалізовано:
- `is_platform` показується як "Platform District"
- `district` показується як окремий бейдж
---
## C) Nodes Layer
### ✅ C1. Node Dashboard
Вже реалізовано в `/nodes/[nodeId]/page.tsx`:
- Metrics Layer (через dashboard API)
- Ownership Layer (через NodeGuardianCard)
- Models Layer (через AIServicesCard)
- Orchestration Layer (через AgentsCard)
### ✅ C2. Міграція nodes
Додано в `migrations.py`:
```sql
CREATE TABLE IF NOT EXISTS nodes (
id TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
hostname TEXT,
owner_microdao_id TEXT REFERENCES microdaos(id),
node_type TEXT,
environment TEXT DEFAULT 'unknown',
cpu_cores INTEGER,
ram_gb INTEGER,
gpu_count INTEGER DEFAULT 0,
disk_gb INTEGER,
status TEXT DEFAULT 'unknown',
guardian_agent_id TEXT,
steward_agent_id TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
```
### ✅ C3. NODE1/NODE2 у nodes
Додано INSERT з ON CONFLICT DO UPDATE:
- `node-1-hetzner-gex44``dao_daarion`, production
- `node-2-macbook-m4max``dao_daarion`, development
---
## D) Backend Fixes
### ✅ D1. /api/agents/* (DAIS, home_node, owner_microdao)
Виправлено в `routes_city.py` та `repo_city.py`:
- Додано `gov_level`, `dais_identity_id`
- Додано `home_microdao_id`, `home_microdao_name`, `home_microdao_slug`
### ✅ D2. /api/microdao/:id/rooms
Вже існує: `GET /city/microdao/{slug}/rooms`
### ✅ D3. /api/nodes/:id/dashboard
Вже існує: `GET /api/v1/nodes/{node_id}/dashboard`
---
## Змінені файли
### Backend (city-service)
- `repo_city.py` — додано gov_level, dais_identity_id, home_microdao до SQL
- `models_city.py` — розширено AgentSummary
- `routes_city.py` — передача нових полів в API
- `migrations.py` — створення таблиці nodes, INSERT NODE1/NODE2
### Frontend (apps/web)
- `src/lib/types/agents.ts` — додано gov_level, dais_identity_id, home_microdao, хелпери
- `src/lib/agent-dashboard.ts` — розширено AgentProfile
- `src/app/agents/page.tsx` — gov-level badge у списку
- `src/components/agent-dashboard/AgentSummaryCard.tsx` — gov-level, DAIS ID, home microDAO
---
## Наступні кроки (рекомендації)
1. **Деплой**: Перезапустити `daarion-city-service` на NODE1 для застосування міграцій
2. **Тестування**: Перевірити UI на https://daarion.space/agents та /nodes
3. **Розширення**: Додати DAIS emails/wallets до API (поки тільки dais_identity_id)
4. **Metrics**: Підключити реальні метрики до Node Dashboard (Prometheus/NATS)
---
**Status: COMPLETED**
**Date: 2025-12-01**

View File

@@ -0,0 +1,39 @@
# MVP DAGI Integration Report — 2025-11-30
## Agents
- **Документи**: `DAARION_Ontology_Core_v1`, `Agent_Governance_Protocol_v1`, `DAARION_Identity_And_Access_Draft_v1`.
- **Бекенд / DAGI**: `services/city-service` (`/city/agents/*`, `/api/v1/agents/*`). Дані з таблиць `agents`, `microdao_members`, `dais_*`. Взаємодія з DAGI через gov-level, DAIS identity, node bindings.
- **Фронтенд**: сторінки `/agents` та `/agents/[agentId]`, API-виклики через `/api/agents/*` -> rewrites -> city-service.
- **Знахідки**:
- Gov-level, DAIS identity, microDAO membership присутні на бекенді та частково в UI (gov-level є у даних, але не всюди відображений).
- Node binding (НОДА1/НОДА2) показується в AgentCard.
- TODO: додати явне відображення DAIS identity та gov-level у UI, а також поля home_microdao_id (частина агентів core_team ще без нього).
## MicroDAO
- **Документи**: `Technical_Description_microdao_PATCH_Ontology`, `microdao_Data_Model_UPDATE_v1`, `microdao_Event_Catalog_EXTENDED_v1`, `MicroDAO_Interface_Architecture_v1`.
- **Бекенд / DAGI**: ендпоїнти `/city/microdao/*`, `/api/v1/microdao/*`. Дані в `microdaos`, `microdao_agents`, `microdao_channels`. Події в `event_outbox` підготовлені, але не всі використовуються в UI.
- **Фронтенд**: `/microdao` і `/governance` (Next.js) — показують список microDAO, базові деталі оркестратора, але не всі канали/кімнати.
- **Знахідки**:
- У БД є 9 активних microDAO (DAARION, Clan, Druid, Eonarch, ENERGYUNION, GREENFOOD, Nutra, SOUL, Yaromir).
- UI відображає базові поля, але ще немає повного Interface Architecture (канали, citizens).
- TODO: завершити MicroDAO Dashboard (канали, rooms, citizens) згідно з документами.
## Nodes
- **Документи**: `Nodes_Interface_Architecture_UPDATE_v1`, `Nodes_Profile_Core_Invariant_PATCH_v1`, `TASK_PHASE_NODE_RUNTIME_AUDIT_NODE1_NODE2`.
- **Бекенд / DAGI**: `/public/nodes`, `/api/nodes/*`, `/city/agents/{id}/dashboard`. Дані беруться з `node_cache` + agent summaries.
- **Фронтенд**: `/nodes`, `/nodes/[nodeId]`. Відображають 4 шари частково (metrics/ownership/orchestration).
- **Знахідки**:
- У `node_cache` є NODE1 (prod) і NODE2 (dev) з guardian/steward агентами.
- UI показує базову інформацію, але Models Layer (Swapper/моделі) ще stub (банер “dashboard WIP”).
- TODO: додати повний Node Dashboard (metrics graf, models list) згідно PATCH v1.
## Summary
- **Agents**: Код ↔ деплой ↔ UI працюють; потрібно лише додати повне відображення gov-level, DAIS і microDAO membership у UI.
- **MicroDAO**: Дані та API готові; UI ще не покриває всі елементи Interface Architecture (канали, citizens, room map).
- **Nodes**: Архітектура (4 шари + Node Core Agents) вже реалізується; UI потребує розширення (metrics/models), а в БД треба додати окрему таблицю `nodes` із microDAO owner для повного інваріанту.
Рекомендації: сформувати `TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_202512XX.md` із конкретними фронтенд/бекенд доопрацюваннями (відображення gov-level/DAIS, Node Dashboard, MicroDAO Dashboard) та створити міграцію `nodes` з полем owner_microdao.

View File

@@ -0,0 +1,33 @@
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' | grep -E '(dagi-|daarion-|gateway)' @ NODE1 (2025-11-30)
Names Image Status
daarion-web daarion-web:latest Up 11 minutes
daarion-city-service daarion-city-service:latest Up 11 minutes (healthy)
dagi-postgres postgres:15-alpine Up 39 minutes
dagi-rbac microdao-daarion-rbac Up 49 minutes (healthy)
dagi-devtools microdao-daarion-devtools Up 49 minutes (healthy)
dagi-crewai microdao-daarion-crewai Up 49 minutes (healthy)
dagi-rag-service microdao-daarion-rag-service Restarting (1) 9 seconds ago
dagi-vector-db-service vector-db-service-vector-db-service Up 17 hours (healthy)
dagi-web-search-service web-search-service-web-search-service Up 17 hours (healthy)
dagi-ocr-service ocr-service-ocr-service Up 24 hours (unhealthy)
dagi-stt-service stt-service-stt-service Up 24 hours (healthy)
dagi-router dagi-router:latest Up 25 hours (healthy)
dagi-node-registry 405a26a6f184 Up 2 days (healthy)
daarion-agents-service daarion-agents-service:latest Up 15 hours
daarion-matrix-gateway daarion-matrix-gateway:latest Up 2 days
daarion-auth daarion-auth Up 3 days (healthy)
daarion-synapse matrixdotorg/synapse:latest Up 3 days (healthy)
daarion-element vectorim/element-web:latest Up 3 days (healthy)
daarion-secondme-service daarion-secondme-service:latest Up 4 days
daarion-microdao-service daarion-microdao-service:latest Up 4 days
daarion-redis redis:7-alpine Up 4 days
dagi-tts daarion-tts:latest Up 6 days (healthy)
dagi-memory-service bbe7e4fe7343 Up 6 days (healthy)
dagi-neo4j-exporter microdao-daarion-neo4j-exporter Up 7 days (healthy)
dagi-neo4j neo4j:5.15-community Up 7 days (healthy)
dagi-nats nats:2-alpine Up 14 hours (healthy)
dagi-image-gen microdao-daarion-image-gen-service Up 8 days (unhealthy)
dagi-qdrant qdrant/qdrant:v1.7.4 Up 9 days
dagi-prometheus prom/prometheus:latest Up 9 days (healthy)
dagi-parser-service microdao-daarion-parser-service Up 9 days (healthy)

View File

@@ -0,0 +1,23 @@
NODE1 healthcheck (2025-11-30)
[city-service]
CMD: curl -s http://localhost:7001/health
OUT: {"status":"healthy","service":"city-service"}
STATUS: OK
[gateway]
CMD: curl -s http://localhost:9300/health
OUT: (connection refused)
STATUS: FAIL (service not reachable on localhost:9300)
[NATS]
CMD: nc -z localhost 4222
OUT: Connection succeeded
STATUS: OK
[Postgres]
CMD: docker exec dagi-postgres psql -U postgres -d postgres -c 'SELECT 1'
OUT: 1
STATUS: OK
Notes: matrix/gateway health endpoint недоступний за localhost:9300 і через DNS-імена; потрібно уточнити адресу сервісу або додати health endpoint.

View File

@@ -0,0 +1,42 @@
# NODE2 Config & Isolation Audit — 2025-11-30
## Context
- Host: локальна dev-нода (MacBook Pro M4 Max).
- Ціль: підтвердити, що NODE2 використовує власні сервіси і не звертається до прод-конфігів NODE1.
- Перевіряли тільки запущені контейнери `docker ps` (див. `docs/debug/node2_containers_20251130.txt`).
---
## Database
- `dagi-postgres` запущений локально з `POSTGRES_DB=daarion_memory`, `POSTGRES_USER=postgres`, `POSTGRES_PASSWORD=postgres`.
- Жоден контейнер не використовує `postgres://...@dagi-postgres:5432/daarion` (прод-БД).
- `dagi-rag-service` має `PG_DSN=postgresql+psycopg2://postgres:postgres@city-db:5432/daarion_city`, але контейнера `city-db` на NODE2 немає → сервіс перезапускається. Потрібно або створити локальний `city-db`, або замінити DSN на `dagi-postgres`/dev-БД.
## NATS
- Локальний контейнер `dagi-nats` (`nats:2-alpine`).
- У `dagi-rag-service` `NATS_URL=nats://nats:4222` (вказує на локальний контейнер, не на NODE1).
- Інших згадок про прод-URL нема.
## Gateway / Matrix / Bots
- `dagi-gateway` використовує локальний `ROUTER_URL=http://router:9102`.
- Телеграм-токени:
- `DAARWIZZ_TELEGRAM_BOT_TOKEN` не задано.
- `HELION_TELEGRAM_BOT_TOKEN=8112062582:...` (dev-токен; перевірити вручну, чи він відрізняється від прод).
- `TELEGRAM_BOT_TOKEN=your_daarwizz_token_here` — placeholder, фактично бот не під'єднаний.
- Matrix / gateway env змінних не виявлено (немає `MATRIX_GATEWAY_URL`).
## Інші секрети / сервіси
- `olagi-router`, `swapper-service`, `stt-service`, `ocr-service`, `image-gen` працюють суто локально (`router`, `host.docker.internal`, тощо).
- Немає `daarion-city-service` та `INTERNAL_API_URL` → dev-нода не запускає міський бекенд.
- Більшість контейнерів у стані `unhealthy` або `Restarting`, але це локальні сервіси; вони не звертаються до NODE1.
## Summary
1. **Перетинів з прод-БД/NATS не виявлено.** Весь стек використовує локальні сервіси.
2. **RAG-service** намагається підключитись до неіснуючого `city-db` → слід оновити `PG_DSN` на локальну БД або вимкнути контейнер.
3. **Gateway токени**: Helion bot має конкретний токен. Потрібно перевірити, чи це dev- або prod-ключ. Якщо це dev — залишити; якщо прод — винести зі stack.
4. **Рекомендації:**
- створити `city-db` (dev) або переписати `PG_DSN``postgresql+psycopg2://postgres:postgres@dagi-postgres:5432/daarion_memory`.
- задокументувати dev-токени в secret manager (щоб не плутати з prod).
- за можливості привести назви контейнерів (nats, router) до `dev-*`, щоб було очевидно, що це dev-стек.
Отже, NODE2 має власний DAGI-стек і не зачіпає прод-конфіги NODE1, але потребує дрібних виправлень (RAG DSN, ревізія токенів).

View File

@@ -0,0 +1,23 @@
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' @ NODE2 (2025-11-30)
NAMES IMAGE STATUS
dagı-rag-service microdao3-rag-service Restarting (1) 37 seconds ago
dagı-router microdao3-router Up 39 minutes (healthy)
dagı-devtools microdao3-devtools Up 39 minutes (healthy)
dagı-rbac microdao3-rbac Up 39 minutes (healthy)
dagı-crewai microdao3-crewai Up 39 minutes (healthy)
dagı-image-gen microdao3-image-gen-service Up 43 minutes (unhealthy)
dagı-tts-service microdao3-tts-service Up 4 hours (unhealthy)
dagı-nats nats:2-alpine Up 5 hours (unhealthy)
dagı-stt-service microdao3-stt-service Up 5 hours (unhealthy)
dagı-prometheus prom/prometheus:latest Up 5 hours (healthy)
dagı-neo4j-exporter microdao3-neo4j-exporter Restarting (0) 25 seconds ago
dagı-neo4j neo4j:5.15-community Restarting (1) 6 seconds ago
o cr-service ocr-service:latest Up 2 days (unhealthy)
swapper-service swapper-service:latest Up 2 days
dagı-web-search-service web-search-service-web-search-service Up 6 days (unhealthy)
dagı-postgres postgres:15-alpine Up 6 days (healthy)
dagı-gateway fa7472f3a8c3 Up 6 days (healthy)
jupyter-lab jupyter/datascience-notebook:latest Up 6 days (healthy)
qdrant-vector-db qdrant/qdrant:latest Up 6 days (unhealthy)
meilisearch-search getmeili/meilisearch:v1.11 Up 6 days (healthy)

View File

@@ -0,0 +1,41 @@
# Node Stack Mismatch — 2025-11-30
## Summary
Під час виконання `TASK_PHASE_NODE_RUNTIME_AUDIT_NODE1_NODE2` знайдені відхилення між фактичними контейнерами та очікуваними профілями нод.
## NODE1 (node-1-hetzner-gex44)
- **Mandatory services**: більшість prod-сервісів присутні (`daarion-city-service`, `daarion-web`, `dagi-router`, `dagi-postgres`, `dagi-nats`, stt/ocr/web-search/rag/vector-db, parser, image-gen тощо).
- **Issues**:
- `dagi-rag-service` у стані `Restarting` → потребує фіксу/перезапуску, інакше DAGI-аналітика/LLM ingestion не працює.
- `dagi-ocr-service` і `dagi-image-gen` позначені як `unhealthy` → треба прогнати healthchecks/логи.
- HTTP health `http://localhost:9300/health` (matrix/gateway) недоступний → потрібно або оновити endpoint, або задокументувати реальну адресу.
- У профайлі очікується `dagi-gateway`, а фактично працює `daarion-matrix-gateway`. Потрібно оновити Node Profile або привести іменування в доку до фактичного контейнера.
## NODE2 (node-2-macbook-m4max)
- **Очікуваний стек**: dev/models (ollama/vllm, experimental services, core-team runtime). Не повинно бути прод-сервісів.
- **Фактичний стан** (локальна машина):
- Запущені `dagi-router`, `dagi-postgres`, `dagi-rbac`, `dagi-devtools`, `dagi-gateway`, `dagi-prometheus`, `nats`, `stt-service`, `ocr-service`, `web-search-service` тощо — це прод-сервіси, які за профілем мають жити на NODE1.
- Більшість контейнерів у стані `unhealthy` або `Restarting` (rag-service, neo4j, nats, stt, tts, web-search).
- Висновок: NODE2 зараз тримає повний стек DAGI, а не лише dev/models. Потрібно або:
- перемістити ці сервіси на NODE1 / іншу інфру (для прод-ролі);
- або оновити профіль NODE2 (якщо вирішено мати прод-сервіси на MacBook, що малоймовірно).
## Recommended Actions
1. **NODE1**
- Розібратися з `dagi-rag-service` (перебудувати образ, перевірити залежності Postgres/NATS/Vector DB).
- Перевірити `dagi-ocr-service`, `dagi-image-gen` (health endpoints та логи).
- Уточнити адресу healthcheck для gateway (чи є окремий endpoint, чи потрібен reverse proxy).
- Оновити Node Profile, щоб узгодити назви (`daarion-matrix-gateway`).
2. **NODE2**
- Зупинити продакшн-сервіси (`dagi-router`, `dagi-postgres`, `dagi-gateway`, `nats`, `stt`, `ocr`, `web-search`, тощо) або перенести їх у dev-версії з чітким неймінгом `dev-*`.
- За потреби залишити тільки dev/models runtime (ollama, swapper, experimental RAG) та відповідно оновити документацію.
- Перевірити/почистити контейнери, що зависли в `unhealthy` / `Restarting` стані.
3. **Документація**
- Відобразити реальний стан у `Node Profiles` + додати посилання на цей файл як доказ невідповідності.

View File

@@ -1,90 +1,39 @@
# Orphan Audit Report — 2025-11-30
# Orphans Audit — 2025-11-30
## 1. Initial State
### Orphan Issues Found:
| Issue | Count | Details |
|-------|-------|---------|
| Agents without DAIS identity | 13 | All governance/lead agents |
| Agents without home_microdao | 4 | ag_atlas, ag_oracle, ag_builder, ag_greeter |
| Node guardian/steward agents missing | 4 | monitor-node1, node-steward-node1, monitor-node2, node-steward-node2 |
### No Issues:
- ✅ MicroDAOs — all have orchestrator_agent_id
- ✅ Orchestrators — all exist in agents table
- ✅ Rooms — all have owner_id and primary_agent_id
Production DB: `daarion` (NODE1)
Ref task: `docs/tasks/TASK_PHASE_MVP_VERIFY_NO_ORPHANS.md`
---
## 2. Fixes Applied
## 1. Nodes
- Технічна таблиця `nodes` у поточній БД відсутня (використовується `node_cache`).
- `node_cache` не містить `microdao_id`, тому перевірка *“нода без microDAO”* наразі неактуальна (TODO у схемі).
- `node_cache` містить `guardian_agent_id` / `steward_agent_id` — обидві ноди мають заповнені значення.
### 2.1. DAIS Identity Links
## 2. Agents
```sql
UPDATE agents SET dais_identity_id = 'dais-<agent_id>'
WHERE id IN (
'daarwizz', 'dario', 'daria',
'soul', 'helion', 'greenfood',
'spirit', 'logic', 'energia',
'clan', 'druid', 'eonarch', 'yaromir'
);
```
| Перевірка | SQL | Результат |
|-----------|-----|-----------|
| Агенти без `home_microdao_id` (крім city-level) | `SELECT id FROM agents WHERE home_microdao_id IS NULL ...` | 0 rows |
| Governance агенти без DAIS identity | `SELECT id FROM agents WHERE dais_identity_id IS NULL AND gov_level IN (...)` | 0 rows |
**Result:** 13 agents now have dais_identity_id
## 3. MicroDAO
### 2.2. Home MicroDAO Links
| Перевірка | Результат |
|-----------|-----------|
| `microdaos` без orchestrator | 0 rows |
| Orchestrator не знайдений у `agents` | 0 rows |
```sql
UPDATE agents SET home_microdao_id = 'dao_daarion'
WHERE id IN ('ag_atlas', 'ag_oracle', 'ag_builder', 'ag_greeter');
```
## 4. Rooms
**Result:** 4 test agents now belong to DAARION DAO
| Перевірка | Результат |
|-----------|-----------|
| `rooms` без owner (`owner_id IS NULL`) | 0 rows |
| City/District rooms без `primary_agent_id` | 0 rows |
---
## 3. Outstanding Items
### Node Guardian/Steward Agents
The `node_cache` table references agents that don't exist:
- `monitor-node1`
- `node-steward-node1`
- `monitor-node2`
- `node-steward-node2`
**Options:**
1. Create these agents (node monitoring infrastructure)
2. Update node_cache to remove references
3. Leave as-is (non-blocking for MVP)
**Decision:** Leave for now — these are infrastructure agents to be created when node monitoring is implemented.
---
## 4. Final Summary
| Metric | Value |
|--------|-------|
| Total Agents | 18 |
| Governance Agents | 6 |
| Agents with DAIS | 13 |
| Agents with Home MicroDAO | 13 |
| Total MicroDAOs | 9 |
| Districts | 3 |
| Total Rooms | 23 |
| Total Nodes | 2 |
### Verified Working:
-`/governance` — shows DAARWIZZ, DARIO, DARIA
-`/agents` — shows all 18 agents
-`/microdao` — shows 9 DAOs (3 districts)
- ✅ City rooms and district rooms functional
---
## 5. Status
**ORPHAN AUDIT: PASSED** (with minor outstanding items for future)
## Summary
- Основні інваріанти виконані: орфанів у `agents`, `microdaos`, `rooms` — немає.
- Для `nodes` потрібно доробити схему (додати `microdao_id` або окрему таблицю), наразі замість цього використовується `node_cache`.
- UI `/nodes`, `/agents`, `/microdao` працюють на актуальних даних.

View File

@@ -64,6 +64,23 @@ Version: 1.1
- `status`
- `registered_at`
## 2.5. Node Profile — Core Invariants (PATCH v1)
Кожна нода в DAARION Ontology має чотири обов'язкові шари:
1. **Metrics Layer** — live-метрики CPU/GPU/RAM/Disk + heartbeat. Навіть якщо телеметрія частково відсутня, нода переходить у `metrics_status = degraded`, а не існує “порожньою”.
2. **Ownership Layer** — власник (MicroDAO/District) з полями `owner_microdao_id`, `owner_microdao_slug` (опційно `district_id`). Немає безхазяйних нод.
3. **Models Layer** — локальний Swapper + набір моделей (LLM, STT, vision, TTS, RAG). Dev-ноди так само мають DAGI-стек, просто з іншим складом моделей.
4. **Orchestration Layer** — локальний DAGI Router + агенти з `home_node_id`, які працюють на цій ноді.
Також кожна нода має мінімальний набір **Node Core Agents**:
- **Node Guardian Agent** — відповідає за health, безпеку, інциденти.
- **Node Steward Agent** — відповідає за приналежність до microDAO, профіль, онбординг.
- (опційно) **Node Models/Swapper Agent** — відповідає за опис і політику використання локального стека моделей.
> Принцип “немає сторінки без агентів” означає, що будь-який інтерфейс Ноди (профіль, метрики, моделі, доступи) завжди “закріплений” за хоча б одним агентом, і цей агент показується в UI.
---
# 3. Типи НОД

View File

@@ -0,0 +1,85 @@
# Nodes Profile Core Invariant — PATCH v1
Version: 1.0
Status: ACTIVE
Parent doc: `docs/foundation/Nodes_Interface_Architecture_UPDATE_v1.md`
---
## 1. Мета
Зафіксувати базовий інваріант DAARION Ontology:
> **Кожна Нода має чотири обов'язкові шари:**
> 1. Metrics Layer
> 2. Ownership Layer
> 3. Models Layer
> 4. Orchestration Layer (DAGI Router + локальні агенти)
Цей патч уніфікує всі ноди (prod, dev, district, core-team) і припиняє трактування, ніби dev-ноди можуть існувати без DAGI-стеку.
---
## 2. Інваріанти
### 2.1 Metrics Layer
- Обов'язкові live-метрики CPU / RAM / GPU / Disk.
- Формат heartbeat з полями `cpu_load`, `memory_used`, `gpu[*].vram_used`, `disk`.
- Якщо метрики відсутні → статус `metrics_status = degraded`, а не “порожня нода”.
### 2.2 Ownership Layer
- Кожна нода належить рівно одному MicroDAO / District.
- Поля: `owner_microdao_id`, `owner_microdao_slug`, `district_id` (опційно).
- В UI обов’язково відображається бейдж MicroDAO.
### 2.3 Models Layer
- На кожній ноді працює локальний Swapper + Model Stack.
- JSON-профіль: `models.llm[]`, `models.vision[]`, `models.stt[]`, `models.tts[]`, `models.rag[]`.
- Немає “нод без моделей” — dev/prod різняться лише складом стека.
### 2.4 Orchestration Layer
- Локальний DAGI Router на кожній ноді.
- Локальні агенти з `home_node_id`.
- Події маршрутизуються через локальний router, який знає про локальні сервіси та підключення до NATS/City Layer.
### 2.5 Node Core Agents & Page Presence
- Мінімум два агенти на ноді:
- **Node Guardian Agent** — health, безпека, інциденти.
- **Node Steward Agent** — приналежність microDAO, онбординг, профіль.
- (опційно) окремий **Node Models/Swapper Agent**.
- Кожна сторінка інтерфейсу, пов’язана з нодою, “закріплена” за щонайменше одним агентом і показує його присутність (немає сторінок “без агентів”).
---
## 3. Вставка в основний документ
Вставити розділ **“Node Profile — Core Invariants (PATCH v1)”** після секції 2.4 (`Запис у таблиці nodes`) у `Nodes_Interface_Architecture_UPDATE_v1.md`.
Текст для вставки:
```md
## Node Profile — Core Invariants (PATCH v1)
Кожна Нода в DAARION Ontology має чотири обов'язкові шари:
1. **Metrics Layer** — live-метрики CPU/GPU/RAM/Disk, heartbeat кожні 60 секунд.
2. **Ownership Layer** — власник (MicroDAO/District) з полями `owner_microdao_id`, `owner_microdao_slug`.
3. **Models Layer** — локальний Swapper + Model Stack (LLM, STT, vision, RAG тощо).
4. **Orchestration Layer** — DAGI Router + локальні агенти з `home_node_id`.
Також кожна нода має мінімальний набір Node Core Agents:
- **Node Guardian Agent** (health, security, інциденти)
- **Node Steward Agent** (приналежність microDAO, профіль)
- (опційно) **Node Models/Swapper Agent**
Жодна сторінка інтерфейсу, що стосується ноди, не існує без агентів, які за неї відповідають (“немає сторінки без агентів”).
```
---
## 4. Next Steps
- Оновити `TASK_PHASE_NODE_RUNTIME_AUDIT_NODE1_NODE2.md`, щоб аудити перевіряли наявність усіх чотирьох шарів та Node Core Agents.
- Підготувати окремий config-аудит dev-ноди (NODE2), щоби переконатися у відокремленості прод- та dev-конфігів.

View File

@@ -0,0 +1,110 @@
# TASK PHASE — MVP DAGI INTEGRATION AUDIT
Version: 1.0
Target: NODE1 (DAARION.space + daarion-city-service)
---
## 1. Мета
Замкнути ланцюг **“документи → код → деплой → UI”** для ключових сутностей MVP (agents, microdao, nodes) і підтвердити, що реалізація відповідає DAGI-онтології.
Вихід: `docs/debug/mvp_dagi_integration_report_<DATE>.md` з фактами та прогалинами.
---
## 2. Agents
### 2.1. Документи
- `docs/foundation/DAARION_Ontology_Core_v1.md`
- `docs/foundation/Agent_Governance_Protocol_v1.md`
- `docs/foundation/DAARION_Identity_And_Access_Draft_v1.md`
Виписати вимоги щодо gov_level, DAIS identity, microDAO membership, видимості.
### 2.2. Backend / DAGI
- API: `/city/agents/*`, `/api/v1/agents/*`, governance ендпоїнти.
- Перевірити джерела даних (`agents`, `microdao_members`, `dais_*`) та інтеграції з DAGI/NATS (статуси агентів, інциденти).
### 2.3. Frontend (Next.js)
- Сторінки `/agents`, `/agents/[agentId]`.
- Переконатися, що через rewrites йдуть на прод-бекенд, а в UI видно gov-level, DAIS, microDAO-поля.
### 2.4. Висновок
- Зафіксувати реалізовані/відсутні елементи.
---
## 3. MicroDAO
### 3.1. Документи
- `docs/foundation/Technical_Description_microdao_PATCH_Ontology.md`
- `docs/foundation/microdao_Data_Model_UPDATE_v1.md`
- `docs/foundation/microdao_Event_Catalog_EXTENDED_v1.md`
- `docs/foundation/MicroDAO_Interface_Architecture_v1.md`
### 3.2. Backend / DAGI
- Ендпоїнти `/city/microdao/*`, `/api/v1/microdao/*`.
- Перевірити зв’язки з агентами, кімнатами, event outbox.
### 3.3. Frontend
- Сторінки `/microdao`, `/microdao/[slug]`, `/governance`.
- Перевірити відображення orchestrator, каналів, кімнат, citizens.
### 3.4. Висновок
- Занотувати реалізовані та відсутні функції.
---
## 4. Nodes
### 4.1. Документи
- `docs/foundation/Nodes_Interface_Architecture_UPDATE_v1.md`
- `docs/foundation/patches/Nodes_Profile_Core_Invariant_PATCH_v1.md`
- `docs/tasks/TASK_PHASE_NODE_RUNTIME_AUDIT_NODE1_NODE2.md`
### 4.2. Backend / DAGI
- API: `/public/nodes`, `/api/nodes/*`, `/city/agents/{id}/dashboard`.
- Перевірити, що Node Core Agents, метрики, власники відображаються з `node_cache`/agent summary.
### 4.3. Frontend
- Сторінки `/nodes`, `/nodes/[nodeId]`.
- Переконатися, що відображаються всі 4 шари (metrics, ownership, models, orchestration).
### 4.4. Висновок
- Описати відповідність та прогалини.
---
## 5. Звіт
Створити `docs/debug/mvp_dagi_integration_report_<DATE>.md` з розділами:
```md
## Agents
- Documents ↔ Code ↔ Deploy ↔ UI
- Findings / Gaps
## MicroDAO
- ...
## Nodes
- ...
## Summary
- Що вже відповідає онтології
- TODO / наступні кроки
```
За потреби підготувати follow-up таск `TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_<DATE>.md`.
---
## 6. Команда для Cursor
```
Виконай, будь ласка, `docs/tasks/TASK_PHASE_MVP_DAGI_INTEGRATION_AUDIT.md`.
Зроби висновок у `docs/debug/mvp_dagi_integration_report_<DATE>.md`,
що реалізовано (док → код → деплой → UI) і де залишились прогалини.
```

View File

@@ -0,0 +1,205 @@
# TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201.md
Version: 1.0
Status: ACTIVE
Target: DAARION.space (NODE1)
Scope: Backend (city-service), Next.js Frontend, DB migrations, Node Profile UI
---
# 1. МЕТА
Замкнути ланцюг **"документи → код → деплой → UI"** для MVP так, щоб:
* всі інваріанти онтології (agents, microDAO, nodes) були відображені в коді й UI;
* DAIS/Agents/MicroDAO/Nodes працювали відповідно до foundation-доків;
* DAGI ↔ MVP працювали узгоджено на NODE1;
* UI не приховував важливу інформацію про агента, microDAO або ноду;
* було ліквідовано всі зафіксовані розриви з `mvp_dagi_integration_report_20251130.md`.
---
# 2. ПЕРЕЛІК НЕОБХІДНИХ ВИПРАВЛЕНЬ (TODO)
---
## A) Agents Layer: поглибити UI відповідно до онтології
### ❗ A1. Додати gov-level у UI (Next.js)
* У списку агентів (`/agents`)
* У профілі агента (`/agents/:agentId`)
* На governance-сторінці (`/governance`)
Поля з БД:
* `gov_level`
* `governance_rank` (якщо є)
* бейджі з документа Agent_Governance_Protocol_v1.md
### ❗ A2. Додати DAIS ID у всі представлення агентів
* DAIS identity (`dais_identities.id`)
* DAIS email(s)
* DAIS wallet(s)
### ❗ A3. Додати microDAO membership для агента
У UI агента показувати:
* "agent belongs to microDAO: <slug>"
* клік → кімнати microDAO
* бейдж microdao_type (regular/district/root)
---
## B) MicroDAO Layer: привести UI до документації
### ❗ B1. Розширити "MicroDAO Dashboard"
На основі:
* MicroDAO_Interface_Architecture_v1.md
* microdao_Data_Model_UPDATE_v1.md
* Rooms_Layer_Architecture_v1.md
Додати:
* список агентів microDAO
* список кімнат microDAO
* список громадян microDAO (напр. microdao_members / agent_assignments)
* бейджі microdao_type (root / district / org / clan / platform)
* кімната microDAO "lobby / help / governance"
### ❗ B2. Показати District-level microDAO як окремий тип
* GREENFOOD
* ENERGYUNION
* SOUL
* CLAN (коли буде протокол)
---
## C) Nodes Layer: вирівняти з онтологією та документами
### ❗ C1. Реалізувати "Node Dashboard (MVP full)"
Згідно:
* Nodes_Profile_Core_Invariant_PATCH_v1.md
* Nodes_Interface_Architecture_UPDATE_v1.md
Додати в `/nodes/:nodeId`:
**Metrics Layer:**
* CPU load
* CPU cores
* RAM total/used
* GPU count
* VRAM total/used
* Disk sizes
**Ownership Layer:**
* owner_microdao
* district_slug
* DAIS-агенти ноди
**Models Layer:**
* Swapper status
* Перелік моделей (стек) у JSON
* Відображення ролей моделей (LLM/coder/vision/etc.)
**Orchestration Layer:**
* Node Core Agents (GuardianOS/Pulse/Atomis)
* agent-count (local_agents)
* health DAGI router
### ❗ C2. Створити міграцію nodes
Додати таблицю `nodes` у PG, щоб перестати залежати від `node_cache`.
Мінімальні поля:
```sql
CREATE TABLE nodes (
id TEXT PRIMARY KEY, -- slug, e.g. node-1-hetzner-gex44
display_name TEXT NOT NULL,
owner_microdao_id TEXT REFERENCES microdaos(id),
node_type TEXT, -- energy, compute, hybrid, iot_gateway
env TEXT, -- production, development, staging
cpu_cores INTEGER,
ram_gb INTEGER,
gpu_count INTEGER DEFAULT 0,
disk_gb INTEGER,
status TEXT DEFAULT 'unknown',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
```
### ❗ C3. Записати NODE1 / NODE2 у `nodes`
* проставити:
- `owner_microdao_id = dao_daarion`
- `home_node_id` для GuardianOS, Pulse, Atomis
---
# D) Backend Fixes
### ❗ D1. Виправити /api/agents/* відповідно до DAIS-шару
Формалізувати:
* dais_identity
* dais_emails[]
* dais_wallets[]
* home_node_id
* owner_microdao_id
### ❗ D2. Додати `/api/microdao/:id/rooms`
Для MicroDAO Dashboard.
### ❗ D3. Виправити `/api/nodes/:id/dashboard`
Зробити відповідно до Nodes Profile (див. C1).
---
# 3. ВИХІДНІ АРТЕФАКТИ
Cursor має створити:
* `docs/debug/mvp_dagi_integration_fix_report_<DATE>.md`
(результати перевірки після фіксів)
* (опціонально) `frontend-diff/` & `backend-diff/`
(всі зміни по UI та API)
---
# 4. КОМАНДА ДЛЯ CURSOR
Після додавання цього файла у репо:
> Виконай, будь ласка,
> `docs/tasks/TASK_PHASE_MVP_DAGI_INTEGRATION_FIX_20251201.md`
> у повному обсязі.
> Створи `docs/debug/mvp_dagi_integration_fix_report_<DATE>.md`,
> і підготуй дифи для backend (FastAPI) та frontend (Next.js).
---
# 5. КРИТЕРІЇ ЗАВЕРШЕННЯ
- [ ] A1-A3: gov-level, DAIS ID, microDAO membership відображаються на сторінках агентів
- [ ] B1-B2: MicroDAO Dashboard показує agents, rooms, citizens, district badge
- [ ] C1-C3: Node Dashboard показує 4 шари (Metrics, Ownership, Models, Orchestration), таблиця `nodes` існує, NODE1/NODE2 записані
- [ ] D1-D3: API повертають повні дані (DAIS, rooms, node dashboard)
- [ ] Звіт `mvp_dagi_integration_fix_report_<DATE>.md` підтверджує, що всі пункти закриті

View File

@@ -0,0 +1,110 @@
# TASK PHASE — NODE2 CONFIG & ISOLATION AUDIT
Version: 1.0
Target: NODE2 (core-team / dev node)
---
## 1. Мета
Переконатися, що dev-нода (NODE2) має **власні конфіги** та не підміняє прод-сервіси NODE1:
- інші `DATABASE_URL`, `NATS_URL`, `MATRIX_GATEWAY_URL`, токени;
- відсутній доступ до прод-БД `daarion` та прод NATS;
- чітке розділення ключів Telegram/Matrix/Email gateway;
- зафіксована політика доступу до DAIS/secretів.
---
## 2. Перевірка контейнерів та змінних середовища
1. На NODE2 виконати:
```bash
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
```
2. Для кожного контейнера DAGI-стеку (`dagi-router`, `dagi-postgres`, `dagi-nats`, `daarion-city-service`, `gateway`, `stt`, `ocr`, `rag`, `vector-db`, `swapper`, тощо) виконати:
```bash
docker inspect <container> \
--format='{{json .Config.Env}}' | jq
```
3. Особливу увагу звернути на ENV:
- `DATABASE_URL`
- `REDIS_URL`
- `NATS_URL`
- `MATRIX_GATEWAY_URL`
- `INTERNAL_API_URL`
- API ключі/токени (Telegram, Discord, Matrix, OAuth)
4. Якщо контейнер використовує `.env` файл — зчитати його (через `docker inspect ... Mounts`).
---
## 3. Виявлення перетинів з PROD
### 3.1. База даних
- Перевірити, що `DATABASE_URL` **не вказує** на `postgres://postgres:postgres@dagi-postgres:5432/daarion`.
- Dev-нода повинна використовувати окрему БД (інший хост/порт або іншу назву БД).
- Якщо все ж використовує прод-БД — зафіксувати це як критичне відхилення.
### 3.2. NATS
- `NATS_URL` має вказувати на локальний/Dev NATS.
- Заборонено використовувати `nats://dagi-nats:4222` з прод-мережі (NODE1).
### 3.3. Gateway / Matrix / Telegram
- Перевірити токени (`TELEGRAM_BOT_TOKEN`, Matrix creds, Discord tokens, тощо).
- Якщо використовуються прод ключі — зафіксувати.
### 3.4. Secrets
- Переконатися, що `daarion-city-service` на NODE2 має **інший** `JWT_SECRET`, `INTERNAL_SECRET`, `AUTH_SERVICE_URL`.
- Перевірити відсутність `.secrets` файлів, спільних із NODE1.
---
## 4. Висновок і логування
1. Створити файл `docs/debug/node2_config_audit_<DATE>.md` з такими секціями:
- `Database`
- `NATS`
- `Gateway/Matrix`
- `Other secrets`
- `Summary`
2. У кожній секції вказати:
- реальні значення (без публікації секретів, лише хости/порти/назви БД);
- чи збігаються вони з прод-конфігом;
- рекомендації (змінити URL/ключ, перенаправити на dev-екземпляр, прибрати контейнер тощо).
3. Якщо знайдені перетини, запропонувати конкретні кроки:
- створити dev БД;
- змінити docker-compose;
- оновити токени в secret manager;
- додати firewall між NODE1/NODE2.
---
## 5. Критерії завершення
- `docs/debug/node2_config_audit_<DATE>.md` заповнений фактами та рекомендаціями;
- Виявлені всі місця, де dev-нода використовує прод-конфіги (якщо є);
- Зроблені пропозиції, як рознести конфіги;
- При необхідності створено follow-up таск (наприклад, `TASK_PHASE_NODE2_CONFIG_FIX.md`).
---
## 6. Команда для Cursor
```
Прошу виконати `docs/tasks/TASK_PHASE_NODE2_CONFIG_AUDIT.md`.
Мета: зібрати docker inspect/env на NODE2, перевірити DATABASE/NATS/Gateway/Secrets,
зробити висновок у `docs/debug/node2_config_audit_<DATE>.md`.
```

View File

@@ -0,0 +1,199 @@
# TASK PHASE — NODE RUNTIME AUDIT (NODE1 & NODE2)
Version: 1.0
Target: NODE1 (production), NODE2 (development)
---
## 1. Мета
Гарантувати, що:
1. У БД рівно дві реальні ноди (NODE1, NODE2) з коректними полями.
2. DAGI-стек на NODE1 відповідає документації (ті сервіси, які мають працювати в проді).
3. NODE2 позначений як development-нода з правильними тегами.
4. UI Node Directory та Node Profile показують саме ці дані.
---
## 2. Перевірка БД (nodes + агенти на ноді)
### 2.1. Список нод
```sql
SELECT id, slug, name, kind, environment, hostname, owner_microdao_id, guardian_agent_id, steward_agent_id
FROM nodes
ORDER BY id;
```
Очікування:
- рівно 2 рядки:
- NODE1 — `Hetzner GEX44 Production` (environment = `production`);
- NODE2 — `MacBook Pro M4 Max` (environment = `development`).
### 2.2. Агенти, прив’язані до нод
Якщо колонка `home_node_id` вже додана:
```sql
SELECT id, slug, display_name, home_node_id, primary_microdao_id
FROM agents
WHERE home_node_id IS NOT NULL AND deleted_at IS NULL
ORDER BY home_node_id, id;
```
Очікування:
- NODE1: інфраструктурні/прод-агенти (router, gateway, guardians);
- NODE2: core-team / AI-runtime агенти (якщо вже зареєстровані).
> Якщо `home_node_id` поки немає — додати TODO у звіт і зафіксувати актуальний стан у README.
---
## 3. Перевірка DAGI-стека на NODE1
### 3.0. Node Profiles (expected DAGI stack)
#### NODE1 — `node-1-hetzner-gex44`
Role: infra / city / production.
Expected services (name mask):
- `dagi-router*`
- `gateway` / `dagi-gateway*`
- `dagi-postgres`
- `dagi-nats`
- `daarion-city-service`
- `daarion-web`
- `dagi-stt-service`
- `dagi-ocr-service`
- `dagi-web-search-service`
- `dagi-rag-service`
- `dagi-vector-db-service`
- інші prod-інтеграції (Matrix gateway, telegram bots, crew router, etc.)
Forbidden / unexpected на NODE1:
- важкі dev/LLM контейнери (ollama, vllm, test models),
- експериментальні сервіси core-team (якщо це не задокументовані прод-сервіси).
#### NODE2 — `node-2-macbook-m4max`
Role: development / models / ai-runtime.
Expected services:
- `ollama`, `vllm`, `text-gen` або інші LLM runtime контейнери,
- dev/test RAG, vision, STT модулі,
- core-team agents / experimental gateways.
Forbidden / unexpected на NODE2:
- продакшн-сервіси міста (`daarion-city-service`, `dagi-router`, `dagi-postgres`, `dagi-nats`, тощо),
- будь-які критичні інфра-компоненти, які повинні жити лише на NODE1.
### 3.1. Список контейнерів
На NODE1 виконати:
```bash
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" | grep -E "(dagi-|daarion-|gateway)"
```
Результат зберегти у файл `docs/debug/node1_containers_<DATE>.txt`.
Очікуваний перелік (орієнтовно, залежно від compose):
- `dagi-router`, `dagi-gateway`, `dagi-postgres`, `dagi-nats`;
- сервісні контейнери (`dagı-ocr-service`, `dagı-stt-service`, `dagı-web-search-service`, `dagı-rag-service`, `dagı-vector-db-service`, тощо за актуальним `docker-compose` файлом);
- `daarion-city-service`;
- `daarion-web` (якщо працює через docker run).
### 3.2. Healthcheck основних сервісів
Створити скрипт `scripts/node1_healthcheck.sh`:
```bash
#!/usr/bin/env bash
set -e
echo "== NODE1 HEALTHCHECK ==" > /tmp/node1_health_status.txt
{
curl -sf http://daarion-city-service:7001/health && echo "city-service OK"
} || echo "city-service FAILED" >> /tmp/node1_health_status.txt
{
curl -sf http://gateway:9300/health && echo "gateway OK"
} || echo "gateway FAILED" >> /tmp/node1_health_status.txt
{
nc -z dagi-nats 4222 && echo "NATS OK"
} || echo "NATS FAILED" >> /tmp/node1_health_status.txt
{
PGPASSWORD=postgres psql -h dagi-postgres -U postgres -d daarion -c "SELECT 1" && echo "postgres OK"
} || echo "postgres FAILED" >> /tmp/node1_health_status.txt
```
Перенести файл `/tmp/node1_health_status.txt` до `docs/debug/node1_health_<DATE>.txt`.
---
## 4. Перевірка NODE2 (development)
На NODE2 виконати:
```bash
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" | grep -E "(dagi-|daarion-|ollama|models)"
```
Зберегти результат у `docs/debug/node2_containers_<DATE>.txt`.
Очікування:
- NODE2 не має зайвих прод-сервісів (тільки dev/runtime контейнери);
- у таблиці `nodes` для NODE2 стоять теги `development`, `gpu`, `ai_runtime` (або аналогічні).
---
## 5. Перевірка відповідності UI
Після SQL та скриптів:
1. Відкрити `https://daarion.space/nodes` — має бути рівно 2 ноди з правильними даними.
2. Перевірити сторінки:
- `https://daarion.space/nodes/node-1-hetzner-gex44`
- `https://daarion.space/nodes/node-2-macbook-m4max`
Переконатися, що:
- сторінки рендеряться без `Failed to fetch`;
- якщо dashboard ще WIP — показано попереджувальний банер, але базовий профіль працює.
---
## 6. Критерії завершення
- У `nodes` — рівно дві ноди з коректними полями.
- Контейнери DAGI на NODE1 відповідають очікуваному стеку.
- NODE2 позначений як development-нода без лишніх прод-сервісів.
- У `docs/debug/` збережені файли:
- `node1_containers_<DATE>.txt`
- `node1_health_<DATE>.txt`
- `node2_containers_<DATE>.txt`
- UI `/nodes` та сторінки нод працюють без помилок і показують актуальні дані.
---
## 7. Запуск таска в Cursor
В чаті Cursor (репозиторій `microdao-daarion`) надіслати:
> Виконай, будь ласка,
> `docs/tasks/TASK_PHASE_NODE_RUNTIME_AUDIT_NODE1_NODE2.md`
> по кроках, як описано в документі.
> Мета: підтвердити, що в БД рівно дві ноди, DAGI-стек на NODE1 відповідає очікуваному, NODE2 відмічений як development, і UI `/nodes` та сторінки нод показують ці дані.
> Особливий акцент: порівняй реальний список контейнерів з розділом **Node Profiles**. Якщо є розбіжності (відсутній обов’язковий сервіс або запущено заборонений), створи файл `docs/debug/node_stack_mismatch_<DATE>.md` з описом фактів і пропозицією дій (зупинити/додати сервіс, створити таск на майбутнє).

View File

@@ -41,6 +41,46 @@ async def run_migrations():
""")
logger.info("Migration: Added room_role, is_public, sort_order to city_rooms table.")
# TASK C2: Create nodes table with owner_microdao (replaces node_cache for ontology)
await conn.execute("""
CREATE TABLE IF NOT EXISTS nodes (
id TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
hostname TEXT,
owner_microdao_id TEXT REFERENCES microdaos(id),
node_type TEXT,
environment TEXT DEFAULT 'unknown',
cpu_cores INTEGER,
ram_gb INTEGER,
gpu_count INTEGER DEFAULT 0,
disk_gb INTEGER,
status TEXT DEFAULT 'unknown',
guardian_agent_id TEXT,
steward_agent_id TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
""")
logger.info("Migration: Created nodes table with owner_microdao.")
# TASK C3: Insert NODE1 and NODE2 if not exist
await conn.execute("""
INSERT INTO nodes (id, display_name, hostname, owner_microdao_id, node_type, environment, status, guardian_agent_id, steward_agent_id)
VALUES
('node-1-hetzner-gex44', 'Hetzner GEX44 Production', '144.76.224.179', 'dao_daarion', 'compute', 'production', 'online', 'monitor-node1', 'node-steward-node1'),
('node-2-macbook-m4max', 'MacBook Pro M4 Max', '192.168.1.33', 'dao_daarion', 'hybrid', 'development', 'online', 'monitor-node2', 'node-steward-node2')
ON CONFLICT (id) DO UPDATE SET
display_name = EXCLUDED.display_name,
hostname = EXCLUDED.hostname,
owner_microdao_id = EXCLUDED.owner_microdao_id,
node_type = EXCLUDED.node_type,
environment = EXCLUDED.environment,
guardian_agent_id = EXCLUDED.guardian_agent_id,
steward_agent_id = EXCLUDED.steward_agent_id,
updated_at = NOW();
""")
logger.info("Migration: Inserted/updated NODE1 and NODE2 in nodes table.")
except Exception as e:
logger.error(f"Error running migrations: {e}")
raise

View File

@@ -306,6 +306,10 @@ class AgentSummary(BaseModel):
node_label: Optional[str] = None # "НОДА1" / "НОДА2"
home_node: Optional[HomeNodeView] = None
# Governance & DAIS (A1, A2)
gov_level: Optional[str] = None # personal, core_team, orchestrator, district_lead, city_governance
dais_identity_id: Optional[str] = None # DAIS identity reference
# Visibility & roles
visibility_scope: str = "city" # global, microdao, private
is_listed_in_directory: bool = True
@@ -313,10 +317,13 @@ class AgentSummary(BaseModel):
is_public: bool = False
is_orchestrator: bool = False # Can create/manage microDAOs
# MicroDAO
# MicroDAO (A3)
primary_microdao_id: Optional[str] = None
primary_microdao_name: Optional[str] = None
primary_microdao_slug: Optional[str] = None
home_microdao_id: Optional[str] = None # Owner microDAO
home_microdao_name: Optional[str] = None
home_microdao_slug: Optional[str] = None
district: Optional[str] = None
microdaos: List[MicrodaoBadge] = []
microdao_memberships: List[Dict[str, Any]] = [] # backward compatibility

View File

@@ -386,10 +386,17 @@ async def list_agent_summaries(
pm.district AS district,
COALESCE(a.public_skills, ARRAY[]::text[]) AS public_skills,
a.crew_team_key,
-- DAIS & Governance fields (A1, A2)
a.gov_level,
a.dais_identity_id,
a.home_microdao_id,
hm.name AS home_microdao_name,
hm.slug AS home_microdao_slug,
COUNT(*) OVER() AS total_count
FROM agents a
LEFT JOIN node_cache nc ON a.node_id = nc.node_id
LEFT JOIN microdaos pm ON a.primary_microdao_id = pm.id
LEFT JOIN microdaos hm ON a.home_microdao_id = hm.id
WHERE {where_sql}
ORDER BY a.display_name
LIMIT ${len(params) + 1} OFFSET ${len(params) + 2}

View File

@@ -184,14 +184,21 @@ async def list_agents(
node_id=agent.get("node_id"),
node_label=agent.get("node_label"),
home_node=home_node,
# Governance & DAIS (A1, A2)
gov_level=agent.get("gov_level"),
dais_identity_id=agent.get("dais_identity_id"),
visibility_scope=agent.get("visibility_scope", "city"),
is_listed_in_directory=agent.get("is_listed_in_directory", True),
is_system=agent.get("is_system", False),
is_public=agent.get("is_public", False),
is_orchestrator=agent.get("is_orchestrator", False),
# MicroDAO (A3)
primary_microdao_id=agent.get("primary_microdao_id"),
primary_microdao_name=agent.get("primary_microdao_name"),
primary_microdao_slug=agent.get("primary_microdao_slug"),
home_microdao_id=agent.get("home_microdao_id"),
home_microdao_name=agent.get("home_microdao_name"),
home_microdao_slug=agent.get("home_microdao_slug"),
district=agent.get("district"),
microdaos=microdaos,
microdao_memberships=agent.get("microdao_memberships", []),