feat(foundation): FOUNDATION_UPDATE implementation
## Documentation (20 files) - DAARION Ontology Core v1 (Agent → MicroDAO → Node → District) - User Onboarding & Identity Layer (DAIS) - Data Model UPDATE, Event Catalog, Governance & Permissions - Rooms Layer, City/MicroDAO/Agents/Nodes Interface Architecture - Helper files: ontology-summary, lifecycles, event-schemas ## Database Migration (027) - DAIS tables: dais_identities, dais_emails, dais_wallets, dais_keys - agent_assignments table for Assignment Layer - rooms table for Rooms Layer - event_outbox for NATS event delivery - New enums: agent_role, microdao_type, node_kind, node_status, etc. - Updated agents, microdaos, nodes tables with ontology fields ## Backend - DAIS service & routes (/api/v1/dais/*) - Assignment service & routes (/api/v1/assignments/*) - Domain types for DAIS and Ontology ## Frontend - Ontology types (Agent, MicroDAO, Node, DAIS, Assignments) - API clients for DAIS and Assignments - UI components: DaisProfileCard, AssignmentsPanel, OntologyBadge Non-breaking update - all existing functionality preserved.
This commit is contained in:
@@ -55,6 +55,7 @@ logs/
|
||||
*-FIX.md
|
||||
*-REPORT.md
|
||||
*-SUMMARY.md
|
||||
!docs/foundation/helpers/ontology-summary.md
|
||||
*-SUCCESS.md
|
||||
*-DEPLOYMENT.md
|
||||
*-QUICKSTART.md
|
||||
|
||||
@@ -15,6 +15,9 @@ import { vendorRoutes } from './api/http/vendor.routes';
|
||||
import { platformsRoutes } from './api/http/platforms.routes';
|
||||
import { agentsRoutes } from './api/http/agents.routes';
|
||||
import { teamsRoutes } from './api/http/teams.routes';
|
||||
// Foundation Update routes
|
||||
import daisRoutes from './http/dais.routes';
|
||||
import assignmentRoutes from './http/assignment.routes';
|
||||
|
||||
const app = express();
|
||||
|
||||
@@ -32,6 +35,10 @@ app.use('/api/v1/platforms', platformsRoutes);
|
||||
app.use('/api/v1/platforms', vendorRoutes); // Vendor routes under platforms
|
||||
app.use('/api/v1', agentsRoutes);
|
||||
|
||||
// Foundation Update routes (DAIS & Assignments)
|
||||
app.use('/api/v1/dais', daisRoutes);
|
||||
app.use('/api/v1/assignments', assignmentRoutes);
|
||||
|
||||
// Health check
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok' });
|
||||
|
||||
93
backend/domain/dais/types.ts
Normal file
93
backend/domain/dais/types.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* DAIS - DAARION Autonomous Identity System
|
||||
* Based on: docs/foundation/DAARION_Identity_And_Access_Draft_v1.md
|
||||
*/
|
||||
|
||||
// Trust levels for DAIS identity
|
||||
export type DaisTrustLevel = 'guest' | 'agent' | 'verified' | 'orchestrator' | 'operator';
|
||||
|
||||
// DAIS Identity
|
||||
export interface DaisIdentity {
|
||||
id: string;
|
||||
did: string; // format: did:daarion:<uuid>
|
||||
defaultEmail?: string;
|
||||
defaultWallet?: string;
|
||||
matrixHandle?: string; // format: @<agent_id>:matrix.daarion.city
|
||||
trustLevel: DaisTrustLevel;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// DAIS Email identity
|
||||
export interface DaisEmail {
|
||||
id: string;
|
||||
daisId: string;
|
||||
email: string;
|
||||
verified: boolean;
|
||||
verifiedAt?: Date;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
// DAIS Wallet identity
|
||||
export interface DaisWallet {
|
||||
id: string;
|
||||
daisId: string;
|
||||
walletAddress: string;
|
||||
network: 'evm' | 'ton' | 'solana';
|
||||
verified: boolean;
|
||||
verifiedAt?: Date;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
// DAIS Key types
|
||||
export type DaisKeyType = 'ed25519' | 'x25519' | 'secp256k1';
|
||||
|
||||
// DAIS Public Key
|
||||
export interface DaisKey {
|
||||
id: string;
|
||||
daisId: string;
|
||||
keyType: DaisKeyType;
|
||||
publicKey: string;
|
||||
createdAt: Date;
|
||||
revokedAt?: Date;
|
||||
}
|
||||
|
||||
// Full DAIS profile with all identities
|
||||
export interface DaisProfile {
|
||||
identity: DaisIdentity;
|
||||
emails: DaisEmail[];
|
||||
wallets: DaisWallet[];
|
||||
keys: DaisKey[];
|
||||
}
|
||||
|
||||
// Create DAIS identity request
|
||||
export interface CreateDaisRequest {
|
||||
email?: string;
|
||||
walletAddress?: string;
|
||||
network?: 'evm' | 'ton' | 'solana';
|
||||
}
|
||||
|
||||
// Verify email request
|
||||
export interface VerifyEmailRequest {
|
||||
daisId: string;
|
||||
email: string;
|
||||
otp: string;
|
||||
}
|
||||
|
||||
// Connect wallet request (SIWE)
|
||||
export interface ConnectWalletRequest {
|
||||
daisId: string;
|
||||
walletAddress: string;
|
||||
network: 'evm' | 'ton' | 'solana';
|
||||
signature: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
// DAIS creation result
|
||||
export interface DaisCreationResult {
|
||||
identity: DaisIdentity;
|
||||
agentId: string;
|
||||
matrixHandle: string;
|
||||
}
|
||||
|
||||
285
backend/domain/ontology/types.ts
Normal file
285
backend/domain/ontology/types.ts
Normal file
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* DAARION Ontology Types
|
||||
* Based on: docs/foundation/DAARION_Ontology_Core_v1.md
|
||||
*
|
||||
* Core hierarchy: Agent → MicroDAO → Node → District
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// AGENT
|
||||
// ============================================================================
|
||||
|
||||
export type AgentRole = 'regular' | 'orchestrator';
|
||||
export type ServiceScope = 'microdao' | 'district' | 'city';
|
||||
|
||||
export interface Agent {
|
||||
id: string;
|
||||
daisIdentityId?: string;
|
||||
homeMicrodaoId: string; // Required by ontology
|
||||
homeNodeId?: string;
|
||||
role: AgentRole;
|
||||
serviceScope?: ServiceScope;
|
||||
|
||||
// Existing fields
|
||||
name: string;
|
||||
kind: string;
|
||||
isOrchestrator: boolean;
|
||||
isPublic: boolean;
|
||||
visibilityScope?: string;
|
||||
primaryMicrodaoId?: string;
|
||||
nodeId?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export type AgentType =
|
||||
| 'personal' // User's personal agent
|
||||
| 'service' // Service/infrastructure agent
|
||||
| 'core-city' // DAARION108 - citywide agents
|
||||
| 'orchestrator'; // Can create MicroDAO
|
||||
|
||||
// ============================================================================
|
||||
// MICRODAO
|
||||
// ============================================================================
|
||||
|
||||
export type MicrodaoType = 'root' | 'standard' | 'district';
|
||||
|
||||
export interface Microdao {
|
||||
id: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
type: MicrodaoType;
|
||||
primaryOrchestratorAgentId: string; // Required by ontology
|
||||
parentMicrodaoId?: string; // For districts
|
||||
walletAddress?: string;
|
||||
|
||||
// Existing fields
|
||||
ownerAgentId?: string;
|
||||
orchestratorAgentId?: string;
|
||||
isPlatform: boolean;
|
||||
isActive: boolean;
|
||||
isPublic: boolean;
|
||||
district?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// NODE
|
||||
// ============================================================================
|
||||
|
||||
export type NodeKind =
|
||||
| 'smartphone'
|
||||
| 'laptop'
|
||||
| 'edge'
|
||||
| 'datacenter'
|
||||
| 'iot'
|
||||
| 'gpu-cluster';
|
||||
|
||||
export type NodeStatus =
|
||||
| 'provisioning'
|
||||
| 'active'
|
||||
| 'draining'
|
||||
| 'retired';
|
||||
|
||||
export interface NodeCapabilities {
|
||||
cpu?: string;
|
||||
ram?: string;
|
||||
gpu?: {
|
||||
name: string;
|
||||
vram?: string;
|
||||
unified_memory_gb?: number;
|
||||
};
|
||||
network?: {
|
||||
up: string;
|
||||
down: string;
|
||||
};
|
||||
sensors?: string[];
|
||||
modules?: Array<{
|
||||
id: string;
|
||||
status: string;
|
||||
port?: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
id: string;
|
||||
nodeId: string;
|
||||
name: string;
|
||||
microdaoId: string; // Required by ontology
|
||||
kind: NodeKind;
|
||||
status: NodeStatus;
|
||||
capabilities: NodeCapabilities;
|
||||
lastHeartbeat?: Date;
|
||||
|
||||
// Existing fields
|
||||
gpu?: Record<string, unknown>;
|
||||
modules?: Array<Record<string, unknown>>;
|
||||
roles?: string[];
|
||||
version?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// DISTRICT (MicroDAO with type='district')
|
||||
// ============================================================================
|
||||
|
||||
export interface District extends Microdao {
|
||||
type: 'district';
|
||||
childMicrodaos: Microdao[];
|
||||
nodePool: Node[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// AGENT ASSIGNMENT
|
||||
// ============================================================================
|
||||
|
||||
export type AssignmentScope = 'microdao' | 'district' | 'city';
|
||||
export type AssignmentRole = 'advisor' | 'security' | 'mentor' | 'ops' | 'core-team' | 'member';
|
||||
|
||||
export interface AgentAssignment {
|
||||
id: string;
|
||||
agentId: string;
|
||||
targetMicrodaoId: string;
|
||||
scope: AssignmentScope;
|
||||
role: AssignmentRole;
|
||||
startTs: Date;
|
||||
endTs?: Date;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
export interface CreateAssignmentRequest {
|
||||
agentId: string;
|
||||
targetMicrodaoId: string;
|
||||
scope: AssignmentScope;
|
||||
role: AssignmentRole;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface EndAssignmentRequest {
|
||||
assignmentId: string;
|
||||
endTs?: Date;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ROOMS LAYER
|
||||
// ============================================================================
|
||||
|
||||
export type RoomType =
|
||||
| 'city-room'
|
||||
| 'dao-room'
|
||||
| 'front-room'
|
||||
| 'agent-room'
|
||||
| 'event-room'
|
||||
| 'district-room';
|
||||
|
||||
export type RoomVisibility =
|
||||
| 'private'
|
||||
| 'members'
|
||||
| 'public-city'
|
||||
| 'public-global';
|
||||
|
||||
export type SpaceScope = 'city' | 'microdao' | 'district';
|
||||
|
||||
export interface Room {
|
||||
id: string;
|
||||
ownerType: 'city' | 'microdao' | 'district' | 'agent';
|
||||
ownerId: string;
|
||||
type: RoomType;
|
||||
spaceScope: SpaceScope;
|
||||
visibility: RoomVisibility;
|
||||
name: string;
|
||||
description?: string;
|
||||
matrixRoomId?: string;
|
||||
isPortal: boolean;
|
||||
portalTargetMicrodaoId?: string;
|
||||
mapX?: number;
|
||||
mapY?: number;
|
||||
zone?: string;
|
||||
meshId?: string;
|
||||
primaryAgentId?: string;
|
||||
teamAgentIds?: string[];
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EVENTS (for NATS)
|
||||
// ============================================================================
|
||||
|
||||
export interface DomainEvent {
|
||||
eventId: string;
|
||||
timestamp: string; // ISO8601
|
||||
version: string;
|
||||
subject: string;
|
||||
payload: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface AgentPromotedEvent extends DomainEvent {
|
||||
subject: 'dagion.agent.promoted_to_orchestrator';
|
||||
payload: {
|
||||
agentId: string;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface MicrodaoCreatedEvent extends DomainEvent {
|
||||
subject: 'dagion.microdao.created';
|
||||
payload: {
|
||||
microdaoId: string;
|
||||
primaryOrchestratorAgentId: string;
|
||||
type: MicrodaoType;
|
||||
parentMicrodaoId?: string;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface NodeRegisteredEvent extends DomainEvent {
|
||||
subject: 'dagion.node.registered';
|
||||
payload: {
|
||||
nodeId: string;
|
||||
microdaoId: string;
|
||||
nodeKind: NodeKind;
|
||||
capabilities: NodeCapabilities;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface MicrodaoPromotedToDistrictEvent extends DomainEvent {
|
||||
subject: 'dagion.microdao.promoted_to_district';
|
||||
payload: {
|
||||
microdaoId: string;
|
||||
promotedByAgentId: string;
|
||||
parentMicrodaoId?: string;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AssignmentCreatedEvent extends DomainEvent {
|
||||
subject: 'dagion.agent.assignment_created';
|
||||
payload: {
|
||||
assignmentId: string;
|
||||
agentId: string;
|
||||
targetMicrodaoId: string;
|
||||
scope: AssignmentScope;
|
||||
role: string;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AssignmentEndedEvent extends DomainEvent {
|
||||
subject: 'dagion.agent.assignment_ended';
|
||||
payload: {
|
||||
assignmentId: string;
|
||||
agentId: string;
|
||||
timestamp: string;
|
||||
};
|
||||
}
|
||||
|
||||
188
backend/http/assignment.routes.ts
Normal file
188
backend/http/assignment.routes.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* Agent Assignment API Routes
|
||||
* Based on: docs/foundation/microdao_Governance_And_Permissions_v1.md
|
||||
*/
|
||||
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { assignmentService } from '../services/assignment/assignment.service';
|
||||
import { logger } from '../infra/logger/logger';
|
||||
|
||||
const router = Router();
|
||||
|
||||
/**
|
||||
* POST /api/assignments
|
||||
* Create a new agent assignment
|
||||
*/
|
||||
router.post('/', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { agentId, targetMicrodaoId, scope, role, metadata } = req.body;
|
||||
|
||||
const assignment = await assignmentService.createAssignment({
|
||||
agentId,
|
||||
targetMicrodaoId,
|
||||
scope,
|
||||
role,
|
||||
metadata,
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: assignment,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to create assignment', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to create assignment',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* DELETE /api/assignments/:id
|
||||
* End an agent assignment
|
||||
*/
|
||||
router.delete('/:id', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await assignmentService.endAssignment(id);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Assignment ended',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to end assignment', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to end assignment',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/assignments/agent/:agentId
|
||||
* Get all active assignments for an agent
|
||||
*/
|
||||
router.get('/agent/:agentId', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { agentId } = req.params;
|
||||
|
||||
const assignments = await assignmentService.getAgentAssignments(agentId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: assignments,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get agent assignments', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get assignments',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/assignments/microdao/:microdaoId
|
||||
* Get all assignments for a MicroDAO
|
||||
*/
|
||||
router.get('/microdao/:microdaoId', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { microdaoId } = req.params;
|
||||
|
||||
const assignments = await assignmentService.getMicrodaoAssignments(microdaoId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: assignments,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get microdao assignments', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get assignments',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/assignments/citywide
|
||||
* Get all citywide assignments (DAARION108)
|
||||
*/
|
||||
router.get('/citywide', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const assignments = await assignmentService.getCitywideAssignments();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: assignments,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get citywide assignments', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get assignments',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/assignments/agent/:agentId/scope
|
||||
* Get agent's effective scope
|
||||
*/
|
||||
router.get('/agent/:agentId/scope', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { agentId } = req.params;
|
||||
|
||||
const scope = await assignmentService.getAgentScope(agentId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: scope,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get agent scope', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get scope',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/assignments/check
|
||||
* Check if agent has assignment to target
|
||||
*/
|
||||
router.get('/check', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { agentId, targetMicrodaoId } = req.query;
|
||||
|
||||
if (!agentId || !targetMicrodaoId) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'agentId and targetMicrodaoId are required',
|
||||
});
|
||||
}
|
||||
|
||||
const hasAssignment = await assignmentService.hasAssignment(
|
||||
agentId as string,
|
||||
targetMicrodaoId as string
|
||||
);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: { hasAssignment },
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to check assignment', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to check assignment',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
219
backend/http/dais.routes.ts
Normal file
219
backend/http/dais.routes.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* DAIS API Routes
|
||||
* Based on: docs/foundation/DAARION_Identity_And_Access_Draft_v1.md
|
||||
*/
|
||||
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { daisService } from '../services/dais/dais.service';
|
||||
import { logger } from '../infra/logger/logger';
|
||||
|
||||
const router = Router();
|
||||
|
||||
/**
|
||||
* POST /api/dais/identity
|
||||
* Create a new DAIS identity
|
||||
*/
|
||||
router.post('/identity', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { email, walletAddress, network } = req.body;
|
||||
|
||||
const result = await daisService.createIdentity({
|
||||
email,
|
||||
walletAddress,
|
||||
network,
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to create DAIS identity', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to create identity',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/dais/:id
|
||||
* Get DAIS profile
|
||||
*/
|
||||
router.get('/:id', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const profile = await daisService.getProfile(id);
|
||||
|
||||
if (!profile) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'DAIS identity not found',
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: profile,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get DAIS profile', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get profile',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/dais/agent/:agentId
|
||||
* Get DAIS profile by agent ID
|
||||
*/
|
||||
router.get('/agent/:agentId', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { agentId } = req.params;
|
||||
const profile = await daisService.getByAgentId(agentId);
|
||||
|
||||
if (!profile) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'DAIS identity not found for agent',
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: profile,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get DAIS by agent', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get profile',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/dais/:id/email
|
||||
* Add email to DAIS
|
||||
*/
|
||||
router.post('/:id/email', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { email } = req.body;
|
||||
|
||||
const result = await daisService.addEmail(id, email);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to add email', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to add email',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/dais/:id/email/verify
|
||||
* Verify email
|
||||
*/
|
||||
router.post('/:id/email/verify', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { email, otp } = req.body;
|
||||
|
||||
// TODO: Validate OTP
|
||||
await daisService.verifyEmail(id, email);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Email verified',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to verify email', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to verify email',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/dais/:id/wallet
|
||||
* Add wallet to DAIS
|
||||
*/
|
||||
router.post('/:id/wallet', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { walletAddress, network } = req.body;
|
||||
|
||||
const result = await daisService.addWallet(id, walletAddress, network);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: result,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to add wallet', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to add wallet',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/dais/:id/wallet/verify
|
||||
* Verify wallet (SIWE)
|
||||
*/
|
||||
router.post('/:id/wallet/verify', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { walletAddress, signature, message } = req.body;
|
||||
|
||||
// TODO: Validate SIWE signature
|
||||
await daisService.verifyWallet(id, walletAddress);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Wallet verified',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to verify wallet', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to verify wallet',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/dais/:id/promote-to-orchestrator
|
||||
* Promote DAIS to orchestrator level
|
||||
*/
|
||||
router.post('/:id/promote-to-orchestrator', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await daisService.promoteToOrchestrator(id);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Promoted to orchestrator',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to promote to orchestrator', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to promote',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
226
backend/services/assignment/assignment.service.ts
Normal file
226
backend/services/assignment/assignment.service.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Agent Assignment Service
|
||||
* Based on: docs/foundation/microdao_Governance_And_Permissions_v1.md
|
||||
*
|
||||
* Manages agent work assignments to other MicroDAO/District/City
|
||||
*/
|
||||
|
||||
import { db } from '../../infra/db/client';
|
||||
import { logger } from '../../infra/logger/logger';
|
||||
import type {
|
||||
AgentAssignment,
|
||||
CreateAssignmentRequest,
|
||||
AssignmentScope,
|
||||
} from '../../domain/ontology/types';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export class AssignmentService {
|
||||
/**
|
||||
* Create a new agent assignment
|
||||
*/
|
||||
async createAssignment(request: CreateAssignmentRequest): Promise<AgentAssignment> {
|
||||
try {
|
||||
const result = await db.query<AgentAssignment>(
|
||||
`INSERT INTO agent_assignments
|
||||
(agent_id, target_microdao_id, scope, role, metadata)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *`,
|
||||
[
|
||||
request.agentId,
|
||||
request.targetMicrodaoId,
|
||||
request.scope,
|
||||
request.role,
|
||||
JSON.stringify(request.metadata || {}),
|
||||
]
|
||||
);
|
||||
|
||||
const assignment = result.rows[0];
|
||||
|
||||
// Publish event to outbox
|
||||
await this.publishEvent('dagion.agent.assignment_created', {
|
||||
assignmentId: assignment.id,
|
||||
agentId: request.agentId,
|
||||
targetMicrodaoId: request.targetMicrodaoId,
|
||||
scope: request.scope,
|
||||
role: request.role,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
logger.info(`Created assignment: ${assignment.id} for agent ${request.agentId}`);
|
||||
return assignment;
|
||||
} catch (error) {
|
||||
logger.error('Failed to create assignment', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End an agent assignment
|
||||
*/
|
||||
async endAssignment(assignmentId: string): Promise<void> {
|
||||
try {
|
||||
const result = await db.query<AgentAssignment>(
|
||||
`UPDATE agent_assignments
|
||||
SET end_ts = now()
|
||||
WHERE id = $1
|
||||
RETURNING *`,
|
||||
[assignmentId]
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
throw new Error(`Assignment not found: ${assignmentId}`);
|
||||
}
|
||||
|
||||
const assignment = result.rows[0];
|
||||
|
||||
// Publish event to outbox
|
||||
await this.publishEvent('dagion.agent.assignment_ended', {
|
||||
assignmentId,
|
||||
agentId: assignment.agentId,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
logger.info(`Ended assignment: ${assignmentId}`);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to end assignment: ${assignmentId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active assignments for an agent
|
||||
*/
|
||||
async getAgentAssignments(agentId: string): Promise<AgentAssignment[]> {
|
||||
try {
|
||||
const result = await db.query<AgentAssignment>(
|
||||
`SELECT * FROM agent_assignments
|
||||
WHERE agent_id = $1 AND end_ts IS NULL
|
||||
ORDER BY created_at DESC`,
|
||||
[agentId]
|
||||
);
|
||||
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get assignments for agent: ${agentId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all assignments for a MicroDAO
|
||||
*/
|
||||
async getMicrodaoAssignments(microdaoId: string): Promise<AgentAssignment[]> {
|
||||
try {
|
||||
const result = await db.query<AgentAssignment>(
|
||||
`SELECT a.*, ag.name as agent_name
|
||||
FROM agent_assignments a
|
||||
JOIN agents ag ON ag.id = a.agent_id
|
||||
WHERE a.target_microdao_id = $1 AND a.end_ts IS NULL
|
||||
ORDER BY a.created_at DESC`,
|
||||
[microdaoId]
|
||||
);
|
||||
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get assignments for microdao: ${microdaoId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get citywide assignments (DAARION108)
|
||||
*/
|
||||
async getCitywideAssignments(): Promise<AgentAssignment[]> {
|
||||
try {
|
||||
const result = await db.query<AgentAssignment>(
|
||||
`SELECT a.*, ag.name as agent_name
|
||||
FROM agent_assignments a
|
||||
JOIN agents ag ON ag.id = a.agent_id
|
||||
WHERE a.scope = 'city' AND a.end_ts IS NULL
|
||||
ORDER BY a.created_at DESC`,
|
||||
[]
|
||||
);
|
||||
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
logger.error('Failed to get citywide assignments', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if agent has assignment to target
|
||||
*/
|
||||
async hasAssignment(agentId: string, targetMicrodaoId: string): Promise<boolean> {
|
||||
try {
|
||||
const result = await db.query(
|
||||
`SELECT 1 FROM agent_assignments
|
||||
WHERE agent_id = $1 AND target_microdao_id = $2 AND end_ts IS NULL
|
||||
LIMIT 1`,
|
||||
[agentId, targetMicrodaoId]
|
||||
);
|
||||
|
||||
return result.rows.length > 0;
|
||||
} catch (error) {
|
||||
logger.error('Failed to check assignment', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get agent's effective scope (home + assignments)
|
||||
*/
|
||||
async getAgentScope(agentId: string): Promise<{
|
||||
homeMicrodaoId: string | null;
|
||||
assignments: AgentAssignment[];
|
||||
effectiveScope: AssignmentScope;
|
||||
}> {
|
||||
try {
|
||||
// Get agent's home MicroDAO
|
||||
const agent = await db.query(
|
||||
`SELECT home_microdao_id, agent_service_scope FROM agents WHERE id = $1`,
|
||||
[agentId]
|
||||
);
|
||||
|
||||
if (agent.rows.length === 0) {
|
||||
throw new Error(`Agent not found: ${agentId}`);
|
||||
}
|
||||
|
||||
const assignments = await this.getAgentAssignments(agentId);
|
||||
|
||||
// Determine effective scope
|
||||
let effectiveScope: AssignmentScope = 'microdao';
|
||||
|
||||
if (agent.rows[0].agent_service_scope === 'city') {
|
||||
effectiveScope = 'city';
|
||||
} else if (assignments.some(a => a.scope === 'city')) {
|
||||
effectiveScope = 'city';
|
||||
} else if (assignments.some(a => a.scope === 'district')) {
|
||||
effectiveScope = 'district';
|
||||
}
|
||||
|
||||
return {
|
||||
homeMicrodaoId: agent.rows[0].home_microdao_id,
|
||||
assignments,
|
||||
effectiveScope,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get agent scope: ${agentId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish event to outbox for NATS
|
||||
*/
|
||||
private async publishEvent(eventType: string, payload: Record<string, unknown>): Promise<void> {
|
||||
await db.query(
|
||||
`INSERT INTO event_outbox (event_type, subject, payload)
|
||||
VALUES ($1, $2, $3)`,
|
||||
[eventType, eventType, JSON.stringify(payload)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const assignmentService = new AssignmentService();
|
||||
|
||||
278
backend/services/dais/dais.service.ts
Normal file
278
backend/services/dais/dais.service.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* DAIS Service - DAARION Autonomous Identity System
|
||||
* Based on: docs/foundation/DAARION_Identity_And_Access_Draft_v1.md
|
||||
*/
|
||||
|
||||
import { db } from '../../infra/db/client';
|
||||
import { logger } from '../../infra/logger/logger';
|
||||
import type {
|
||||
DaisIdentity,
|
||||
DaisProfile,
|
||||
DaisEmail,
|
||||
DaisWallet,
|
||||
CreateDaisRequest,
|
||||
DaisCreationResult,
|
||||
DaisTrustLevel,
|
||||
} from '../../domain/dais/types';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export class DaisService {
|
||||
/**
|
||||
* Create a new DAIS identity
|
||||
*/
|
||||
async createIdentity(request: CreateDaisRequest): Promise<DaisCreationResult> {
|
||||
const id = `dais-${uuidv4()}`;
|
||||
const did = `did:daarion:${uuidv4()}`;
|
||||
|
||||
try {
|
||||
// Create DAIS identity
|
||||
const identity = await db.query<DaisIdentity>(
|
||||
`INSERT INTO dais_identities (id, did, default_email, default_wallet, trust_level)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *`,
|
||||
[id, did, request.email || null, request.walletAddress || null, 'agent']
|
||||
);
|
||||
|
||||
// Add email if provided
|
||||
if (request.email) {
|
||||
await db.query(
|
||||
`INSERT INTO dais_emails (dais_id, email, verified)
|
||||
VALUES ($1, $2, false)`,
|
||||
[id, request.email]
|
||||
);
|
||||
}
|
||||
|
||||
// Add wallet if provided
|
||||
if (request.walletAddress) {
|
||||
await db.query(
|
||||
`INSERT INTO dais_wallets (dais_id, wallet_address, network, verified)
|
||||
VALUES ($1, $2, $3, false)`,
|
||||
[id, request.walletAddress, request.network || 'evm']
|
||||
);
|
||||
}
|
||||
|
||||
// Create agent linked to DAIS
|
||||
const agentId = `agent-${uuidv4()}`;
|
||||
const matrixHandle = `@${agentId}:matrix.daarion.city`;
|
||||
|
||||
await db.query(
|
||||
`INSERT INTO agents (id, name, kind, dais_identity_id, agent_role, home_microdao_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)`,
|
||||
[agentId, 'New Agent', 'personal', id, 'regular', 'daarion']
|
||||
);
|
||||
|
||||
// Update DAIS with matrix handle
|
||||
await db.query(
|
||||
`UPDATE dais_identities SET matrix_handle = $1 WHERE id = $2`,
|
||||
[matrixHandle, id]
|
||||
);
|
||||
|
||||
logger.info(`Created DAIS identity: ${id}, agent: ${agentId}`);
|
||||
|
||||
return {
|
||||
identity: identity.rows[0],
|
||||
agentId,
|
||||
matrixHandle,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Failed to create DAIS identity', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DAIS profile with all linked identities
|
||||
*/
|
||||
async getProfile(daisId: string): Promise<DaisProfile | null> {
|
||||
try {
|
||||
const identity = await db.query<DaisIdentity>(
|
||||
`SELECT * FROM dais_identities WHERE id = $1`,
|
||||
[daisId]
|
||||
);
|
||||
|
||||
if (identity.rows.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const emails = await db.query<DaisEmail>(
|
||||
`SELECT * FROM dais_emails WHERE dais_id = $1`,
|
||||
[daisId]
|
||||
);
|
||||
|
||||
const wallets = await db.query<DaisWallet>(
|
||||
`SELECT * FROM dais_wallets WHERE dais_id = $1`,
|
||||
[daisId]
|
||||
);
|
||||
|
||||
const keys = await db.query(
|
||||
`SELECT * FROM dais_keys WHERE dais_id = $1 AND revoked_at IS NULL`,
|
||||
[daisId]
|
||||
);
|
||||
|
||||
return {
|
||||
identity: identity.rows[0],
|
||||
emails: emails.rows,
|
||||
wallets: wallets.rows,
|
||||
keys: keys.rows,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get DAIS profile: ${daisId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DAIS by agent ID
|
||||
*/
|
||||
async getByAgentId(agentId: string): Promise<DaisProfile | null> {
|
||||
try {
|
||||
const agent = await db.query(
|
||||
`SELECT dais_identity_id FROM agents WHERE id = $1`,
|
||||
[agentId]
|
||||
);
|
||||
|
||||
if (agent.rows.length === 0 || !agent.rows[0].dais_identity_id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.getProfile(agent.rows[0].dais_identity_id);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get DAIS by agent: ${agentId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add email to DAIS
|
||||
*/
|
||||
async addEmail(daisId: string, email: string): Promise<DaisEmail> {
|
||||
try {
|
||||
const result = await db.query<DaisEmail>(
|
||||
`INSERT INTO dais_emails (dais_id, email, verified)
|
||||
VALUES ($1, $2, false)
|
||||
RETURNING *`,
|
||||
[daisId, email]
|
||||
);
|
||||
|
||||
logger.info(`Added email to DAIS ${daisId}: ${email}`);
|
||||
return result.rows[0];
|
||||
} catch (error) {
|
||||
logger.error(`Failed to add email to DAIS: ${daisId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify email
|
||||
*/
|
||||
async verifyEmail(daisId: string, email: string): Promise<void> {
|
||||
try {
|
||||
await db.query(
|
||||
`UPDATE dais_emails
|
||||
SET verified = true, verified_at = now()
|
||||
WHERE dais_id = $1 AND email = $2`,
|
||||
[daisId, email]
|
||||
);
|
||||
|
||||
// Update trust level if this is first verified email
|
||||
await this.updateTrustLevel(daisId);
|
||||
|
||||
logger.info(`Verified email for DAIS ${daisId}: ${email}`);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to verify email: ${daisId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add wallet to DAIS
|
||||
*/
|
||||
async addWallet(
|
||||
daisId: string,
|
||||
walletAddress: string,
|
||||
network: 'evm' | 'ton' | 'solana' = 'evm'
|
||||
): Promise<DaisWallet> {
|
||||
try {
|
||||
const result = await db.query<DaisWallet>(
|
||||
`INSERT INTO dais_wallets (dais_id, wallet_address, network, verified)
|
||||
VALUES ($1, $2, $3, false)
|
||||
RETURNING *`,
|
||||
[daisId, walletAddress, network]
|
||||
);
|
||||
|
||||
logger.info(`Added wallet to DAIS ${daisId}: ${walletAddress}`);
|
||||
return result.rows[0];
|
||||
} catch (error) {
|
||||
logger.error(`Failed to add wallet to DAIS: ${daisId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify wallet (after SIWE signature)
|
||||
*/
|
||||
async verifyWallet(daisId: string, walletAddress: string): Promise<void> {
|
||||
try {
|
||||
await db.query(
|
||||
`UPDATE dais_wallets
|
||||
SET verified = true, verified_at = now()
|
||||
WHERE dais_id = $1 AND wallet_address = $2`,
|
||||
[daisId, walletAddress]
|
||||
);
|
||||
|
||||
// Update trust level
|
||||
await this.updateTrustLevel(daisId);
|
||||
|
||||
logger.info(`Verified wallet for DAIS ${daisId}: ${walletAddress}`);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to verify wallet: ${daisId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update trust level based on verified identities
|
||||
*/
|
||||
private async updateTrustLevel(daisId: string): Promise<void> {
|
||||
const profile = await this.getProfile(daisId);
|
||||
if (!profile) return;
|
||||
|
||||
const hasVerifiedEmail = profile.emails.some(e => e.verified);
|
||||
const hasVerifiedWallet = profile.wallets.some(w => w.verified);
|
||||
|
||||
let newLevel: DaisTrustLevel = 'guest';
|
||||
|
||||
if (hasVerifiedEmail && hasVerifiedWallet) {
|
||||
newLevel = 'verified';
|
||||
} else if (hasVerifiedEmail) {
|
||||
newLevel = 'agent';
|
||||
}
|
||||
|
||||
await db.query(
|
||||
`UPDATE dais_identities SET trust_level = $1, updated_at = now() WHERE id = $2`,
|
||||
[newLevel, daisId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote agent to orchestrator (updates DAIS trust level)
|
||||
*/
|
||||
async promoteToOrchestrator(daisId: string): Promise<void> {
|
||||
try {
|
||||
await db.query(
|
||||
`UPDATE dais_identities
|
||||
SET trust_level = 'orchestrator', updated_at = now()
|
||||
WHERE id = $1`,
|
||||
[daisId]
|
||||
);
|
||||
|
||||
logger.info(`Promoted DAIS to orchestrator: ${daisId}`);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to promote to orchestrator: ${daisId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const daisService = new DaisService();
|
||||
|
||||
@@ -313,7 +313,7 @@ services:
|
||||
- dagi-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8890/health"]
|
||||
test: ["CMD-SHELL", "wget -qO- http://localhost:8890/health || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
120
docs/foundation/Agents_Interface_Architecture_v1.md
Normal file
120
docs/foundation/Agents_Interface_Architecture_v1.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Agents_Interface_Architecture_v1.md
|
||||
|
||||
## DAARION.city — Agent-Centric Interface Architecture
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Spec (MVP)
|
||||
**Scope:** Архітектура інтерфейсу агентів: primary_agent, team_agents, кабінети, ролі, кімнати, взаємодія з MicroDAO, Nodes, City.
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Описати агентно-центровану модель інтерфейсу DAARION.space:
|
||||
|
||||
* кожна сторінка має агента-власника,
|
||||
* первинні/командні агенти,
|
||||
* кабінети агентів,
|
||||
* категорії агентів,
|
||||
* кімнати та віжети,
|
||||
* інтеграцію з MicroDAO/City/Nodes.
|
||||
|
||||
---
|
||||
|
||||
# 1. Принцип
|
||||
|
||||
> **Усі сторінки, сцени й кімнати належать агентам (primary_agent).**
|
||||
|
||||
Структура сторінки:
|
||||
|
||||
```json
|
||||
{
|
||||
"primary_agent": "agent_id",
|
||||
"team_agents": ["agent_id_2","agent_id_3"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. Типи агентів
|
||||
|
||||
1. Personal Agents (агенти користувачів).
|
||||
2. Organizational Agents (належать MicroDAO).
|
||||
3. Core-Team Agents (CEO/CTO/LegaI/Architect).
|
||||
4. Public City Agents (DARIO, DARIA, DAARWIZZ, City Info).
|
||||
5. Service/Infrastructure Agents (monitoring, bridge, summarizer).
|
||||
6. District/Platform Agents (Helion, ERP GREENFOOD).
|
||||
|
||||
---
|
||||
|
||||
# 3. Primary vs Team Agents
|
||||
|
||||
* **Primary agent** — господар сцени (City Square → DARIO; MicroDAO Dashboard → Orchestrator).
|
||||
* **Team agents** — асистують (DARIA, Security agent, DevOps agent тощо).
|
||||
|
||||
---
|
||||
|
||||
# 4. Кабінет агента
|
||||
|
||||
* **Profile** — ім’я, DAIS, роль, MicroDAO.
|
||||
* **Activity** — події, дії, лог.
|
||||
* **Rooms** — кімнати агента.
|
||||
* **Workspaces** — проєкти, задачі.
|
||||
* **Nodes** — home node, active session node.
|
||||
* **Tools** — моделі, інтеграції.
|
||||
* **Assignments** — MicroDAO / District / City scope.
|
||||
|
||||
---
|
||||
|
||||
# 5. Agent Rooms
|
||||
|
||||
* Personal room (DM з людиною).
|
||||
* Workspace room (внутрішні).
|
||||
* Public front room (у місті).
|
||||
* Service room (інфраструктура).
|
||||
* District room (платформи).
|
||||
|
||||
---
|
||||
|
||||
# 6. Зв’язки
|
||||
|
||||
* **Agent → MicroDAO**: ролі, дозволи, кімнати, проєкти.
|
||||
* **Agent → Node**: home/active node, ресурси.
|
||||
* **Agent → City**: публічні агенти, кіоски, City Square.
|
||||
|
||||
---
|
||||
|
||||
# 7. Widgets & Actions
|
||||
|
||||
* Кожен віджет має `agent_owner`.
|
||||
* Будь-яка дія (створити MicroDAO, зареєструвати ноду) здійснюється агентом.
|
||||
|
||||
---
|
||||
|
||||
# 8. Agent Lifecycle
|
||||
|
||||
1. Creation (DAIS onboarding).
|
||||
2. Assignment до MicroDAO.
|
||||
3. Node placement.
|
||||
4. Room creation.
|
||||
5. Activity.
|
||||
6. Promotion (core-team/orchestrator).
|
||||
7. Archival.
|
||||
|
||||
---
|
||||
|
||||
# 9. MVP Scope
|
||||
|
||||
* Кабінет агента.
|
||||
* Primary/team agent модель.
|
||||
* Списки персональних/організаційних/публічних агентів.
|
||||
* Agent rooms, projects, nodes.
|
||||
* Присутність агента в City Square.
|
||||
|
||||
---
|
||||
|
||||
# 10. Підсумок
|
||||
|
||||
Агенти — центральні суб’єкти DAARION.space.
|
||||
Цей документ закріплює інтерфейсну модель, у якій кожна сцена має primary_agent та команду агента, а всі функції (місто, MicroDAO, ноди) розгортаються через агентів.
|
||||
|
||||
152
docs/foundation/City_Interface_Architecture_v1.md
Normal file
152
docs/foundation/City_Interface_Architecture_v1.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# City_Interface_Architecture_v1.md
|
||||
|
||||
## DAARION.city — City Layer & Public Space Interface
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Spec (MVP)
|
||||
**Scope:** City Hub, City Square, public rooms, civic agents, MicroDAO portals, 2D/3D map
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити інтерфейс міського рівня DAARION.space:
|
||||
|
||||
* City Hub, City Square, публічні кімнати,
|
||||
* ролі DARIO, DARIA, DAARWIZZ та інших civic-агентів,
|
||||
* публічні кіоски/портали MicroDAO та District,
|
||||
* взаємодію з Rooms Layer і MicroDAO Interface,
|
||||
* 2D/3D представлення.
|
||||
|
||||
---
|
||||
|
||||
# 1. Роль City Layer
|
||||
|
||||
* верхній публічний шар DAARION.space;
|
||||
* перша точка входу для мешканців;
|
||||
* спільний простір для всіх MicroDAO/District/агентів;
|
||||
* місце, де користувачі бачать мапу, кімнати, портали, події.
|
||||
|
||||
---
|
||||
|
||||
# 2. Основні об’єкти
|
||||
|
||||
## 2.1. City Hub
|
||||
|
||||
* належить root MicroDAO `DAARION`;
|
||||
* містить City Square, City Rooms, City Map, реєстр порталів.
|
||||
|
||||
## 2.2. City Square
|
||||
|
||||
* головна публічна сцена;
|
||||
* `primary_agent = DARIO`, `team_agents = [DARIA, DAARWIZZ, civic agents]`;
|
||||
* блоки: привітання, підтримка, публічні кімнати, кіоски MicroDAO та District.
|
||||
|
||||
## 2.3. City Rooms
|
||||
|
||||
* `city.lobby`, `city.news`, `city.events`, `city.help` тощо;
|
||||
* `space_scope='city'`, `owner_type='city'`.
|
||||
|
||||
## 2.4. MicroDAO Portals
|
||||
|
||||
* публічні кімнати `front-room` у місті (Energyunion, GREENFOOD);
|
||||
* ведуть до інтерфейсу конкретного MicroDAO.
|
||||
|
||||
## 2.5. District Portals
|
||||
|
||||
* портали для платформ/екосистем;
|
||||
* ведуть у District Space.
|
||||
|
||||
---
|
||||
|
||||
# 3. Агентність міського інтерфейсу
|
||||
|
||||
* **DARIO** — primary_agent City Square (community manager).
|
||||
* **DARIA** — assistant_agent (tech support).
|
||||
* **DAARWIZZ** — мер міста; бере участь у подіях.
|
||||
* Публічні DAO агенти (Helion, ERP) мають власні front-room.
|
||||
|
||||
---
|
||||
|
||||
# 4. Основні екрани
|
||||
|
||||
1. `/city` — City Square (центральна сцена).
|
||||
2. `/city/rooms` — список публічних кімнат.
|
||||
3. `/city/map` — 2D-мапа з маркерами кімнат і порталів.
|
||||
4. `/city/agents` — каталог публічних агентів (DARIO, DARIA, DAARWIZZ, DAO-агенти).
|
||||
|
||||
---
|
||||
|
||||
# 5. City Square Layout (MVP)
|
||||
|
||||
* **Центр:** DARIO (вітання, пропозиції, вибір MicroDAO).
|
||||
* **Праворуч:** DARIA (FAQ, підтримка, навігація).
|
||||
* **Низ:** публічні кімнати (Новини, Події, Допомога, Лобі).
|
||||
* **Ліворуч:** кіоски MicroDAO (Energyunion, GREENFOOD).
|
||||
* **Верх:** DAARWIZZ + глобальні оголошення.
|
||||
|
||||
---
|
||||
|
||||
# 6. Публічність та присутність
|
||||
|
||||
* City Square — місце, де можуть бути всі авторизовані користувачі, їх агенти та публічні DAO.
|
||||
* MVP: список «хто онлайн» та лічильник присутніх (без 3D).
|
||||
|
||||
---
|
||||
|
||||
# 7. Портали MicroDAO
|
||||
|
||||
* кожне MicroDAO може опублікувати front-office (`space_scope='city'`);
|
||||
* користувач бачить:
|
||||
* якщо не член — публічний профіль + «Приєднатися»;
|
||||
* якщо член — кнопка «Увійти в MicroDAO».
|
||||
|
||||
---
|
||||
|
||||
# 8. Civic Layer
|
||||
|
||||
* DARIO — community manager.
|
||||
* DARIA — технічна підтримка.
|
||||
* DAARWIZZ — мер; участь у «city.events`.
|
||||
|
||||
---
|
||||
|
||||
# 9. API (чернетка)
|
||||
|
||||
* `GET /api/city/rooms`
|
||||
* `GET /api/city/portals`
|
||||
* `GET /api/city/map`
|
||||
* `GET /api/city/agents/public`
|
||||
|
||||
---
|
||||
|
||||
# 10. MVP Scope
|
||||
|
||||
* `/city` з базовими блоками DARIO/DARIA, публічні кімнати, два front-office.
|
||||
* `/city/rooms` як таблиця.
|
||||
* `/city/map` — статична 2D-мінімапа.
|
||||
* Каталог публічних агентів.
|
||||
|
||||
Не входить: повна 3D-мапа, аватари, гейміфікація.
|
||||
|
||||
---
|
||||
|
||||
# 11. Взаємодія з іншими рівнями
|
||||
|
||||
* City Layer → Rooms Layer (`city-room`, `front-room`).
|
||||
* City Layer → MicroDAO Interface (front-office).
|
||||
* City Layer → Agents Layer (primary/team agents).
|
||||
|
||||
---
|
||||
|
||||
# 12. Підсумок
|
||||
|
||||
City Layer робить DAARION.city зрозумілим для мешканців:
|
||||
|
||||
* City Square — головна сцена;
|
||||
* публічні кімнати — спільний простір;
|
||||
* портали MicroDAO — міст між містом і організаціями;
|
||||
* civic-агенти — обличчя міста.
|
||||
|
||||
Документ завершено.
|
||||
|
||||
234
docs/foundation/DAARION_Identity_And_Access_Draft_v1.md
Normal file
234
docs/foundation/DAARION_Identity_And_Access_Draft_v1.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# DAARION_Identity_And_Access_Draft_v1.md
|
||||
|
||||
## DAIS — DAARION Autonomous Identity System (Draft IAM Specification)
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Draft (Foundation Update)
|
||||
**Scope:** DAIS identity, wallets, keys, access control, DID, recovery
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити проектну модель системи ідентичності та доступу в DAARION.city:
|
||||
|
||||
* як створюється DAIS-ідентичність;
|
||||
* як зв’язуються email, wallet, ключі, DID, Matrix;
|
||||
* як визначаються рівні довіри;
|
||||
* як працює key rotation та recovery;
|
||||
* як DAIS пов’язаний із Agent/MicroDAO/Node;
|
||||
* як реалізований доступ на рівні сервісів (gateway, node, worker).
|
||||
|
||||
Документ — фундамент IAM-модуля. Він не ламає поточну архітектуру, а задає майбутні вимоги.
|
||||
|
||||
---
|
||||
|
||||
# 1. Концепція DAIS
|
||||
|
||||
DAIS (DAARION Autonomous Identity System) — універсальна цифрова ідентичність, яка належить **агенту** й використовується для:
|
||||
|
||||
* створення агента,
|
||||
* входу в MicroDAO,
|
||||
* авторизації на нодах,
|
||||
* підписання подій у DAGI Mesh,
|
||||
* економічних операцій,
|
||||
* відновлення доступу.
|
||||
|
||||
---
|
||||
|
||||
# 2. Структура DAIS-ідентичності
|
||||
|
||||
```
|
||||
DAIS Identity
|
||||
├─ Email identities (1..N)
|
||||
├─ Wallet identities (1..N)
|
||||
│ ├─ EVM (Polygon)
|
||||
│ ├─ TON (future)
|
||||
│ └─ Hardware wallet (future)
|
||||
├─ DID (decentralized identifier)
|
||||
├─ Matrix handle
|
||||
├─ Public keys
|
||||
├─ Signature domains
|
||||
├─ Recovery methods
|
||||
└─ Metadata
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. Компоненти DAIS
|
||||
|
||||
## 3.1. Email identities
|
||||
|
||||
* Passwordless (OTP / Magic Link).
|
||||
* Можна прив’язати кілька email.
|
||||
* Використовується як low-security login.
|
||||
|
||||
## 3.2. Wallet identities
|
||||
|
||||
* Підтримка EVM wallets (MetaMask, Rabby, WalletConnect).
|
||||
* SIWE як стандарт підпису.
|
||||
* Wallet є high-security login.
|
||||
|
||||
## 3.3. DID
|
||||
|
||||
* формат: `did:daariion:<uuid>`
|
||||
* використовується для підписання подій, міжнодових операцій, Matrix.
|
||||
|
||||
## 3.4. Matrix handle
|
||||
|
||||
* `@<agent_id>:matrix.daarion.city`
|
||||
* для міжагентного чату, голосових каналів, presence.
|
||||
|
||||
## 3.5. Public Keys
|
||||
|
||||
| Тип ключа | Призначення |
|
||||
|-----------|--------------------------|
|
||||
| Ed25519 | підпис подій, автентифікація |
|
||||
| X25519 | шифрування / E2EE |
|
||||
| secp256k1 | wallet-сумісність |
|
||||
|
||||
## 3.6. Signature domains
|
||||
|
||||
* `dais.login`
|
||||
* `dais.node-auth`
|
||||
* `dais.microdao-action`
|
||||
* `dais.agent-auth`
|
||||
* `dais.recovery`
|
||||
|
||||
## 3.7. Metadata
|
||||
|
||||
```json
|
||||
{
|
||||
"avatar": "...",
|
||||
"telegram_linked": false,
|
||||
"created_at": "...",
|
||||
"citizenship_level": "basic"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4. Рівні довіри DAIS (Trust Levels)
|
||||
|
||||
| Рівень | Назва | Вимоги | Права |
|
||||
|--------|---------------------|----------------------------------------|---------------------|
|
||||
| 0 | Guest | email only | базові функції |
|
||||
| 1 | Agent | підтверджений email | створення агента |
|
||||
| 2 | Verified Agent | email + wallet | доступ до AI/DAO |
|
||||
| 3 | Orchestrator | SIWE + токени/ролі | створення MicroDAO |
|
||||
| 4 | DAARION Operator | hardware keys (future) | city governance |
|
||||
|
||||
---
|
||||
|
||||
# 5. Зберігання (схема)
|
||||
|
||||
```sql
|
||||
dais_identities (
|
||||
id text primary key,
|
||||
default_email text null,
|
||||
default_wallet text null,
|
||||
did text not null,
|
||||
trust_level integer not null default 1,
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
dais_emails (
|
||||
id uuid primary key,
|
||||
dais_id text not null references dais_identities(id),
|
||||
email text not null,
|
||||
verified boolean not null default false
|
||||
);
|
||||
|
||||
dais_wallets (
|
||||
id uuid primary key,
|
||||
dais_id text not null references dais_identities(id),
|
||||
wallet_address text not null,
|
||||
network text not null default 'evm',
|
||||
verified boolean not null default false
|
||||
);
|
||||
|
||||
dais_keys (
|
||||
dais_id text not null references dais_identities(id),
|
||||
key_type text not null,
|
||||
public_key text not null
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 6. Взаємозв’язок DAIS → Agent → MicroDAO → Node
|
||||
|
||||
```
|
||||
DAIS identity
|
||||
↓ (автоматично)
|
||||
Agent (home_microdao = DAARION)
|
||||
↓ (через promotion)
|
||||
MicroDAO (створюється оркестратором)
|
||||
↓
|
||||
Node (реєструється MicroDAO)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. Рівні доступу
|
||||
|
||||
## 7.1. Application (UI)
|
||||
|
||||
* Email OTP / Magic link / SIWE.
|
||||
* Доступ до кабінету агента, MicroDAO, сервісів.
|
||||
|
||||
## 7.2. Services (Gateway/API)
|
||||
|
||||
* Авторизація через DID, public keys, короткоживучі токени.
|
||||
|
||||
## 7.3. Node Access
|
||||
|
||||
* Нода перевіряє DAIS-ключ (`dais.node-auth`).
|
||||
|
||||
---
|
||||
|
||||
# 8. Ротація ключів
|
||||
|
||||
* **Soft rotation:** заміна email, прив’язка нового wallet, оновлення Matrix handle.
|
||||
* **Hard rotation:** новий DID, нові ключі Ed25519/X25519 (потрібен підпис wallet).
|
||||
|
||||
---
|
||||
|
||||
# 9. Recovery
|
||||
|
||||
* Recovery email (secondary addresses).
|
||||
* Seed phrase wallet recovery.
|
||||
* Social recovery (future) — 2-3 поручителі (агенти, MicroDAO core team, DAARION108).
|
||||
|
||||
---
|
||||
|
||||
# 10. DAIS та безпека DAGI Mesh
|
||||
|
||||
DAIS використовується для:
|
||||
|
||||
* підписання міжагентних повідомлень;
|
||||
* валідації подій у DAGI Router;
|
||||
* E2EE у Matrix;
|
||||
* авторизації worker-нод;
|
||||
* запуску міжнодових контейнерів.
|
||||
|
||||
Без DAIS неможливо створити агента, MicroDAO, ноду чи увійти в District.
|
||||
|
||||
---
|
||||
|
||||
# 11. Майбутні розширення
|
||||
|
||||
* Інтеграція TON;
|
||||
* DID-compatible wallet auth;
|
||||
* hardware keys;
|
||||
* локальна біометрія (без передачі).
|
||||
|
||||
---
|
||||
|
||||
# 12. Підсумок
|
||||
|
||||
DAIS — це цифрове тіло кожного агента.
|
||||
Воно забезпечує універсальний login, права доступу, підписи, recovery.
|
||||
Документ задає базу для майбутнього IAM і не потребує змін у чинній логіці.
|
||||
|
||||
239
docs/foundation/DAARION_Ontology_Core_v1.md
Normal file
239
docs/foundation/DAARION_Ontology_Core_v1.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# DAARION_Ontology_Core_v1.md
|
||||
|
||||
## DAARION.city — Ontology Core (Agent → MicroDAO → Node → District)
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Document (Immutable Core)
|
||||
**Scope:** DAARION.city / microDAO / DAGI Mesh / Identity Layer (DAIS)
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Цей документ встановлює **базову онтологію** міста DAARION.city:
|
||||
структуру сутностей, їх ролі, інваріанти та правила взаємодії.
|
||||
|
||||
Це — фундаментальна модель, на якій будуються:
|
||||
|
||||
* User Onboarding
|
||||
* Identity Layer (DAIS)
|
||||
* MicroDAO Governance
|
||||
* Node Registration
|
||||
* Agent Networks
|
||||
* District Architecture
|
||||
* DAGI Mesh Routing
|
||||
|
||||
Документ є **неламким** (non-breaking): будь-які зміни мають бути сумісні назад і розширювати, а не замінювати тут визначені принципи.
|
||||
|
||||
---
|
||||
|
||||
# 1. Онтологічний каркас DAARION.city
|
||||
|
||||
Уся мережа базується на простій ієрархії:
|
||||
|
||||
**Agent → MicroDAO → Node → District**
|
||||
|
||||
Жодна сутність не може існувати поза цією структурою.
|
||||
|
||||
---
|
||||
|
||||
# 2. Agent
|
||||
|
||||
## 2.1. Опис
|
||||
|
||||
**Agent** — мінімальна одиниця DAARION.city.
|
||||
Кожен агент має:
|
||||
|
||||
* унікальний цифровий профіль (**DAIS Identity**);
|
||||
* власний «Кабінет агента» (Agent Console);
|
||||
* ключі, криптогаманець, DID/Matrix-ідентичність;
|
||||
* базову приналежність до однієї MicroDAO (`home_microdao_id`);
|
||||
* базову ноду виконання (`home_node_id`);
|
||||
* власні ролі та сфери діяльності.
|
||||
|
||||
## 2.2. Типи агентів
|
||||
|
||||
| Тип агента | Опис | Приписка | Сфера діяльності |
|
||||
| -------------------------------- | ----------------------------- | ------------------------------------------------- | ---------------------------- |
|
||||
| **Personal Agent** | стандартний агент користувача | обов'язкова | своя MicroDAO або root-місто |
|
||||
| **Service/Infrastructure Agent** | технічні агенти сервісів | до MicroDAO, де вони розгорнуті (частіше DAARION) | мікроДАО / дістрик / місто |
|
||||
| **Core-City Agent (DAARION108)** | головна команда з 108 агентів | root MicroDAO «DAARION» | citywide (все місто) |
|
||||
| **Orchestrator Agent** | має право створювати MicroDAO | обов'язкова | керування MicroDAO |
|
||||
|
||||
## 2.3. Ролі
|
||||
|
||||
* `regular` — стандартний агент.
|
||||
* `orchestrator` — агент, який може створювати і керувати MicroDAO.
|
||||
|
||||
## 2.4. Інваріанти Agent
|
||||
|
||||
1. Agent не може існувати без DAIS-ідентичності.
|
||||
2. Agent завжди має одну `home_microdao_id`.
|
||||
3. Agent завжди має хоч одну ноду виконання (мінімально — root-ноду DAARION).
|
||||
4. Orchestrator — це підвищений стан агента, який активується лише при виконанні умов доступу (токени, ключі).
|
||||
5. Усі Service/Infrastructure-агенти «приписані» до реальної MicroDAO та реальної ноди.
|
||||
|
||||
---
|
||||
|
||||
# 3. MicroDAO
|
||||
|
||||
## 3.1. Опис
|
||||
|
||||
**MicroDAO** — мінімальна організаційна одиниця в місті:
|
||||
команда, спільнота, проєкт, ініціатива або економічна клітинка.
|
||||
|
||||
## 3.2. Ключові характеристики
|
||||
|
||||
* унікальний `microdao_id`;
|
||||
* `primary_orchestrator_agent_id` — головний агент;
|
||||
* свій криптогаманець DAIS;
|
||||
* свій governance-модуль;
|
||||
* свої кімнати/канали/робочі простори;
|
||||
* можливість реєструвати **Node**.
|
||||
|
||||
## 3.3. Типи MicroDAO
|
||||
|
||||
* **root** — перша MicroDAO, місто DAARION;
|
||||
* **standard** — звичайні MicroDAO користувачів;
|
||||
* **district** — розширений режим MicroDAO з доступом до інфраструктури і підлеглих MicroDAO.
|
||||
|
||||
## 3.4. Інваріанти MicroDAO
|
||||
|
||||
1. MicroDAO не може існувати без одного основного Orchestrator-Agent.
|
||||
2. Root MicroDAO (DAARION) існує завжди і є предком усіх інших MicroDAO.
|
||||
3. Кожна MicroDAO може реєструвати одну або більше нод.
|
||||
4. District — це **форма MicroDAO**, а не окрема сутність.
|
||||
5. Жодна MicroDAO не може існувати «без агресора» (без керуючого агента).
|
||||
|
||||
---
|
||||
|
||||
# 4. Node
|
||||
|
||||
## 4.1. Опис
|
||||
|
||||
**Node** — реальний вузол виконання в DAGI Mesh:
|
||||
|
||||
* смартфон,
|
||||
* ноутбук,
|
||||
* edge-пристрій,
|
||||
* сервер,
|
||||
* GPU-кластер,
|
||||
* IoT-шлюз.
|
||||
|
||||
Це **не абстракція** — тільки фізично або програмно реальні пристрої.
|
||||
|
||||
## 4.2. Характеристики
|
||||
|
||||
* `node_id`;
|
||||
* `microdao_id` — кому належить нода;
|
||||
* `node_kind`: `smartphone`, `laptop`, `edge`, `datacenter`, `iot`, `gpu-cluster`;
|
||||
* `capabilities` (GPU, RAM, sensors, network);
|
||||
* `status`: `provisioning`, `active`, `draining`, `retired`.
|
||||
|
||||
## 4.3. Інваріанти Node
|
||||
|
||||
1. Node **завжди** належить одній MicroDAO.
|
||||
2. Не існує «безхозних», «тестових» або «системних» нод поза моделлю.
|
||||
3. Вся базова інфраструктура DAARION.city належить root MicroDAO «DAARION».
|
||||
4. Агент може виконуватись лише:
|
||||
* на ноді своєї MicroDAO,
|
||||
* або на ноді MicroDAO/District, які на це дали дозвіл (governance).
|
||||
|
||||
---
|
||||
|
||||
# 5. District
|
||||
|
||||
## 5.1. Опис
|
||||
|
||||
**District** — це MicroDAO, якій надано розширені повноваження для керування:
|
||||
|
||||
* підлеглими MicroDAO,
|
||||
* мережами нод,
|
||||
* економічними або галузевими кластерами.
|
||||
|
||||
## 5.2. Інваріанти District
|
||||
|
||||
1. District = MicroDAO з `type = district`.
|
||||
2. District має `parent_microdao_id`.
|
||||
3. District може керувати ресурсами нижчих MicroDAO без зміни їх власності над нодами.
|
||||
4. District — це елемент ієрархії, але не новий тип сутності.
|
||||
|
||||
---
|
||||
|
||||
# 6. Assignment Layer (Агенти, які працюють у різних MicroDAO)
|
||||
|
||||
## 6.1. Опис
|
||||
|
||||
Agent може «приходити на роботу» або виконувати завдання:
|
||||
|
||||
* в іншій MicroDAO,
|
||||
* в District,
|
||||
* у всьому місті (DAARION108).
|
||||
|
||||
Це робиться без зміни:
|
||||
|
||||
* `home_microdao_id`,
|
||||
* `home_node_id`,
|
||||
* ролі (regular / orchestrator).
|
||||
|
||||
## 6.2. Сутність `agent_assignment`
|
||||
|
||||
Визначає:
|
||||
«цей агент виконує роботу для іншої MicroDAO/District».
|
||||
|
||||
Поля:
|
||||
|
||||
* `agent_id`
|
||||
* `target_microdao_id`
|
||||
* `scope` (`microdao`, `district`, `city`)
|
||||
* `role` (`advisor`, `ops`, `security`, `mentor`, `core-team`)
|
||||
* `start_ts`, `end_ts`
|
||||
|
||||
## 6.3. Інваріанти Assignment
|
||||
|
||||
1. Assignment не змінює приписку агента.
|
||||
2. DAARION108 мають `scope = city`.
|
||||
3. Service/Infrastructure-агенти можуть мати assignment до всієї мережі.
|
||||
|
||||
---
|
||||
|
||||
# 7. Жорсткі інваріанти онтології (DAARION Law)
|
||||
|
||||
1. **Agent → MicroDAO → Node**
|
||||
— єдина дозволена лінія походження.
|
||||
|
||||
2. **MicroDAO завжди має Orchestrator-Agent.**
|
||||
|
||||
3. **Node завжди належить MicroDAO.**
|
||||
|
||||
4. **District — це розширений режим MicroDAO, не окрема сутність.**
|
||||
|
||||
5. **Немає тестових, тимчасових або віртуальних нод.**
|
||||
Усі ноди справжні та пов'язані з реальними агентами та MicroDAO.
|
||||
|
||||
6. **Новий користувач завжди починає як Agent, приписаний до root-мікроДАО DAARION.**
|
||||
|
||||
7. **Тільки Orchestrator-Agent може створити MicroDAO.**
|
||||
|
||||
---
|
||||
|
||||
# 8. Стратегічна мета онтології
|
||||
|
||||
Створити **міцний, простий, ідеально зрозумілий фундамент**
|
||||
для нового типу Інтернету:
|
||||
|
||||
**Інтернет агентів та нод.**
|
||||
|
||||
На цій онтології будуть побудовані:
|
||||
|
||||
* модуль DAIS Identity,
|
||||
* Agent Governance,
|
||||
* Node Registration / Verification,
|
||||
* District Platforms,
|
||||
* розподілене планування DAGI Mesh,
|
||||
* і вся економіка міста DAARION.city.
|
||||
|
||||
---
|
||||
|
||||
Документ готовий до включення в TASK_PHASE_FOUNDATION_UPDATE та подальшої розробки.
|
||||
|
||||
161
docs/foundation/MicroDAO_Interface_Architecture_v1.md
Normal file
161
docs/foundation/MicroDAO_Interface_Architecture_v1.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# MicroDAO_Interface_Architecture_v1.md
|
||||
|
||||
## DAARION.city — MicroDAO Interface & Workspace Architecture
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Spec (MVP)
|
||||
**Scope:** UI/UX структури MicroDAO, доступи, кімнати, проєкти, агентні ролі, ноди, front-office
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити повну структуру інтерфейсу MicroDAO:
|
||||
|
||||
* Dashboard,
|
||||
* Rooms,
|
||||
* Projects/Tasks/Kanban,
|
||||
* Agents/Core-team,
|
||||
* Members (люди + агенти),
|
||||
* Nodes,
|
||||
* Front-office у місті,
|
||||
* Routing та API.
|
||||
|
||||
MicroDAO — це робочий простір команди / платформи / району.
|
||||
|
||||
---
|
||||
|
||||
# 1. Структура інтерфейсу MicroDAO
|
||||
|
||||
Кожне MicroDAO має 7 основних блоків:
|
||||
|
||||
1. **Dashboard**
|
||||
2. **Rooms**
|
||||
3. **Projects**
|
||||
4. **Agents**
|
||||
5. **Members**
|
||||
6. **Nodes**
|
||||
7. **Front-Office**
|
||||
|
||||
---
|
||||
|
||||
# 2. Dashboard
|
||||
|
||||
Показує:
|
||||
|
||||
* назву, логотип, тип (`root/standard/district`);
|
||||
* опис;
|
||||
* основні метрики (агенти, люди, ноди, проєкти);
|
||||
* оркестратора та core-team;
|
||||
* сповіщення, останні події;
|
||||
* кнопку «Вийти у Front-Office».
|
||||
|
||||
---
|
||||
|
||||
# 3. Rooms
|
||||
|
||||
* внутрішні кімнати (general, core-team, dev, projects);
|
||||
* публічні кімнати (front-office) із `publish_to_city`;
|
||||
* портальні кімнати (посилання на District, підлеглі DAO).
|
||||
|
||||
---
|
||||
|
||||
# 4. Projects Layer
|
||||
|
||||
* Projects: назва, опис, команда, кімната, канбан.
|
||||
* Tasks: title, description, status, assignee (agent/human), due date.
|
||||
* Kanban: MVP — три стовпці.
|
||||
|
||||
---
|
||||
|
||||
# 5. Agents Layer
|
||||
|
||||
* Personal agents (людей), organizational, core-team, service.
|
||||
* Перегляд агента: DAIS, rooms, projects, nodes, assignments.
|
||||
* Core-team агенти мають розширені повноваження.
|
||||
|
||||
---
|
||||
|
||||
# 6. Members Layer
|
||||
|
||||
* Люди (humans) як учасники.
|
||||
* Кожна людина керує своїми агентами.
|
||||
* Ролі: `member`, `manager`, `core-team`, `orchestrator`.
|
||||
|
||||
---
|
||||
|
||||
# 7. Nodes Layer
|
||||
|
||||
* Список нод MicroDAO, їх статусів, ресурсів.
|
||||
* Прив’язка агентів до нод.
|
||||
* Доступні дії (реєстрація, оновлення, вимкнення).
|
||||
|
||||
---
|
||||
|
||||
# 8. Front-Office
|
||||
|
||||
* Публічний портал MicroDAO у City Hub.
|
||||
* Показує публічну інформацію, агента-вітрину, кнопку «приєднатися».
|
||||
|
||||
---
|
||||
|
||||
# 9. District Mode
|
||||
|
||||
* District = MicroDAO з `type='district'`.
|
||||
* Має власну міні-мапу.
|
||||
* Управляє підлеглими MicroDAO та нодами.
|
||||
* Відображає дружні DAO на окремій панелі.
|
||||
|
||||
---
|
||||
|
||||
# 10. Routing
|
||||
|
||||
```
|
||||
/microdao/{id}/dashboard
|
||||
/microdao/{id}/rooms
|
||||
/microdao/{id}/projects
|
||||
/microdao/{id}/agents
|
||||
/microdao/{id}/members
|
||||
/microdao/{id}/nodes
|
||||
/microdao/{id}/front
|
||||
```
|
||||
|
||||
District:
|
||||
|
||||
```
|
||||
/district/{id}
|
||||
/district/{id}/rooms
|
||||
/district/{id}/ecosystem
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 11. Інтеграції
|
||||
|
||||
* Rooms Layer — кімнати DAO, front-room.
|
||||
* City Layer — front-office у місті.
|
||||
* Agents Layer — primary_agent кожної сцени.
|
||||
* Nodes Layer — таб «Nodes».
|
||||
|
||||
---
|
||||
|
||||
# 12. 3D/2D перспектива
|
||||
|
||||
* Параметри кімнат/порталів зберігають `map_x`, `map_y`, `mesh_id`.
|
||||
* У майбутньому MicroDAO може мати власний 3D-офіс.
|
||||
|
||||
---
|
||||
|
||||
# 13. MVP Scope
|
||||
|
||||
* Dashboard + Rooms + Projects + Agents + Members + Nodes + Front-Office.
|
||||
* Без 3D, без складних governance workflows.
|
||||
|
||||
---
|
||||
|
||||
# 14. Підсумок
|
||||
|
||||
MicroDAO Interface — серце DAARION.space.
|
||||
Він забезпечує роботу команд, агентів, нод і публічних порталів, інтегруючись із City та Rooms Layer.
|
||||
Документ задає канонічну структуру для реалізації MVP.
|
||||
|
||||
199
docs/foundation/Nodes_Interface_Architecture_v1.md
Normal file
199
docs/foundation/Nodes_Interface_Architecture_v1.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Nodes_Interface_Architecture_v1.md
|
||||
|
||||
## DAARION.city — Nodes Interface & Node Management Architecture
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Spec (MVP)
|
||||
**Scope:** Node dashboards, control rooms, node registration, capabilities, health monitoring, DAGI mesh integration
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити інтерфейс керування нодами в DAARION.city:
|
||||
|
||||
* як відображаються ноди в UI,
|
||||
* як реєструються та верифікуються ноди,
|
||||
* як моніториться здоров'я та ресурси,
|
||||
* як ноди інтегруються з MicroDAO та DAGI Mesh,
|
||||
* як агенти виконуються на нодах,
|
||||
* як відбувається координація Node Fleet.
|
||||
|
||||
---
|
||||
|
||||
# 1. Роль Nodes Interface
|
||||
|
||||
Nodes Interface — це шар управління фізичними та логічними вузлами DAGI Mesh:
|
||||
|
||||
* відображення стану нод MicroDAO,
|
||||
* реєстрація нових нод,
|
||||
* моніторинг ресурсів (CPU, GPU, RAM, network),
|
||||
* управління lifecycle нод,
|
||||
* прив'язка агентів до нод,
|
||||
* fleet management для District.
|
||||
|
||||
---
|
||||
|
||||
# 2. Типи нод
|
||||
|
||||
| Тип | Опис | Capabilities |
|
||||
|-----|------|--------------|
|
||||
| `smartphone` | мобільний пристрій | low compute, camera, GPS, sensors |
|
||||
| `laptop` | персональний комп'ютер | mid compute, local LLM, development |
|
||||
| `edge` | edge device | low-mid compute, IoT gateway |
|
||||
| `datacenter` | серверна інфраструктура | high compute, GPU, 24/7 |
|
||||
| `iot` | IoT пристрій | sensors, actuators, minimal compute |
|
||||
| `gpu-cluster` | GPU-кластер | high GPU, ML inference/training |
|
||||
|
||||
---
|
||||
|
||||
# 3. Структура Node Dashboard
|
||||
|
||||
## 3.1. Node Overview
|
||||
|
||||
* `node_id`, `node_kind`
|
||||
* `microdao_id` — власник ноди
|
||||
* `status`: provisioning | active | draining | retired
|
||||
* `capabilities` — ресурси (CPU, GPU, RAM, network)
|
||||
* Останній heartbeat
|
||||
* Кількість активних агентів
|
||||
|
||||
## 3.2. Health Metrics
|
||||
|
||||
* CPU utilization
|
||||
* Memory usage
|
||||
* GPU utilization (якщо є)
|
||||
* Network throughput
|
||||
* Latency до mesh router
|
||||
* Uptime
|
||||
|
||||
## 3.3. Agent Sessions
|
||||
|
||||
* Список агентів, що виконуються на ноді
|
||||
* Статус кожного агента (active, idle, error)
|
||||
* Ресурси, зайняті агентом
|
||||
|
||||
---
|
||||
|
||||
# 4. Реєстрація ноди
|
||||
|
||||
## 4.1. Flow
|
||||
|
||||
1. Оркестратор MicroDAO обирає "Register Node".
|
||||
2. Вказує тип ноди (`node_kind`).
|
||||
3. Генерується provisioning token.
|
||||
4. Пристрій завантажує DAGI agent та вводить token.
|
||||
5. Нода автентифікується через DAIS node-auth.
|
||||
6. Подія `node.registered` публікується в NATS.
|
||||
7. Нода переходить у `provisioning`, потім `active`.
|
||||
|
||||
## 4.2. Інваріанти
|
||||
|
||||
* Нода завжди належить MicroDAO.
|
||||
* Реєстрацію ініціює Orchestrator.
|
||||
* Після реєстрації нода підключається до DAGI Mesh.
|
||||
|
||||
---
|
||||
|
||||
# 5. Екрани інтерфейсу
|
||||
|
||||
## 5.1. MicroDAO Nodes Tab
|
||||
|
||||
* `/microdao/{id}/nodes` — список нод MicroDAO
|
||||
* Таблиця: node_id, kind, status, capabilities, agents, actions
|
||||
* Кнопка "Register Node"
|
||||
|
||||
## 5.2. Node Detail
|
||||
|
||||
* `/node/{id}` — деталі ноди
|
||||
* Overview, Health, Agents, Logs, Settings
|
||||
* Actions: restart agents, drain, retire
|
||||
|
||||
## 5.3. Fleet Management (District)
|
||||
|
||||
* `/district/{id}/fleet` — всі ноди підлеглих MicroDAO
|
||||
* Aggregated metrics, alerts
|
||||
* Scheduling policies
|
||||
|
||||
---
|
||||
|
||||
# 6. API Endpoints
|
||||
|
||||
```
|
||||
GET /api/microdao/{id}/nodes
|
||||
POST /api/microdao/{id}/nodes/register
|
||||
GET /api/node/{id}
|
||||
GET /api/node/{id}/health
|
||||
GET /api/node/{id}/agents
|
||||
POST /api/node/{id}/drain
|
||||
POST /api/node/{id}/retire
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. DAGI Mesh Integration
|
||||
|
||||
* Кожна нода підключається до DAGI Router.
|
||||
* Ноди отримують task scheduling від Router.
|
||||
* Агенти виконуються на нодах через Worker Runtime.
|
||||
* Heartbeat кожні 30 секунд до Mesh Controller.
|
||||
|
||||
---
|
||||
|
||||
# 8. Lifecycle Management
|
||||
|
||||
```
|
||||
provisioning → active → draining → retired
|
||||
```
|
||||
|
||||
* **provisioning**: нода реєструється, очікує верифікації.
|
||||
* **active**: нода працює, приймає агентів.
|
||||
* **draining**: нода готується до вимкнення, нові агенти не призначаються.
|
||||
* **retired**: нода офлайн, архівована.
|
||||
|
||||
---
|
||||
|
||||
# 9. Security
|
||||
|
||||
* Доступ до ноди через DAIS node-auth.
|
||||
* Тільки Orchestrator/Core-Team можуть керувати нодами.
|
||||
* Agent sessions ізольовані (container/sandbox).
|
||||
* Всі комунікації шифровані (mTLS).
|
||||
|
||||
---
|
||||
|
||||
# 10. MVP Scope
|
||||
|
||||
* Node list у MicroDAO interface.
|
||||
* Node registration flow.
|
||||
* Basic health display (status, capabilities).
|
||||
* Agent sessions list.
|
||||
* Drain/Retire actions.
|
||||
|
||||
Не входить: advanced scheduling, GPU quotas, auto-scaling.
|
||||
|
||||
---
|
||||
|
||||
# 11. Зв'язок з іншими документами
|
||||
|
||||
* **Ontology** → Node як сутність Agent → MicroDAO → Node → District.
|
||||
* **Data Model** → таблиця `nodes` з полями.
|
||||
* **Event Catalog** → `node.registered`.
|
||||
* **MicroDAO Interface** → Nodes Tab.
|
||||
* **Governance** → права на реєстрацію нод.
|
||||
* **DAIS** → node-auth для автентифікації.
|
||||
|
||||
---
|
||||
|
||||
# 12. Підсумок
|
||||
|
||||
Nodes Interface забезпечує управління фізичною інфраструктурою DAGI Mesh:
|
||||
|
||||
* реєстрацію нод,
|
||||
* моніторинг здоров'я та ресурсів,
|
||||
* виконання агентів,
|
||||
* lifecycle management,
|
||||
* fleet management для District.
|
||||
|
||||
Документ завершено.
|
||||
|
||||
99
docs/foundation/README.md
Normal file
99
docs/foundation/README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Foundation Documentation
|
||||
|
||||
Цей каталог містить **джерело істини** для DAARION.city — повну онтологію, моделі даних, Governance, Identity (DAIS), Rooms Layer та інтерфейси City/MicroDAO/Agents/Nodes.
|
||||
|
||||
---
|
||||
|
||||
## Статус: ✅ FOUNDATION_UPDATE Complete
|
||||
|
||||
**Всього файлів:** 19 (12 основних + 6 helpers + 1 patch)
|
||||
|
||||
---
|
||||
|
||||
## Основні документи (12)
|
||||
|
||||
### Онтологія та ідентичність (1-7)
|
||||
|
||||
| № | Файл | Опис |
|
||||
|---|------|------|
|
||||
| 1 | [`DAARION_Ontology_Core_v1.md`](./DAARION_Ontology_Core_v1.md) | Базова онтологія Agent → MicroDAO → Node → District |
|
||||
| 2 | [`User_Onboarding_And_Identity_Layer_v1.md`](./User_Onboarding_And_Identity_Layer_v1.md) | Реєстрація, DAIS, email/wallet login, Orchestrator |
|
||||
| 3 | [`Technical_Description_microdao_PATCH_Ontology.md`](./Technical_Description_microdao_PATCH_Ontology.md) | Патч онтології до існуючого Technical Description |
|
||||
| 4 | [`microdao_Data_Model_UPDATE_v1.md`](./microdao_Data_Model_UPDATE_v1.md) | Оновлена модель даних: agents, microdaos, nodes, assignments |
|
||||
| 5 | [`microdao_Event_Catalog_EXTENDED_v1.md`](./microdao_Event_Catalog_EXTENDED_v1.md) | Каталог подій NATS: lifecycle, assignment events |
|
||||
| 6 | [`microdao_Governance_And_Permissions_v1.md`](./microdao_Governance_And_Permissions_v1.md) | Ролі, ACL, governance MicroDAO/District |
|
||||
| 7 | [`DAARION_Identity_And_Access_Draft_v1.md`](./DAARION_Identity_And_Access_Draft_v1.md) | DAIS як IAM: DID, keys, wallets, trust levels |
|
||||
|
||||
### Rooms та інтерфейси (8-12)
|
||||
|
||||
| № | Файл | Опис |
|
||||
|---|------|------|
|
||||
| 8 | [`Rooms_Layer_Architecture_v1.md`](./Rooms_Layer_Architecture_v1.md) | City/MicroDAO/District rooms, portals, 2D/3D |
|
||||
| 9 | [`MicroDAO_Interface_Architecture_v1.md`](./MicroDAO_Interface_Architecture_v1.md) | UI MicroDAO: Dashboard, Rooms, Projects, Agents, Nodes |
|
||||
| 10 | [`City_Interface_Architecture_v1.md`](./City_Interface_Architecture_v1.md) | City Square, DARIO/DARIA, public rooms, portals |
|
||||
| 11 | [`Agents_Interface_Architecture_v1.md`](./Agents_Interface_Architecture_v1.md) | Agent-centric UI: primary/team agents, кабінети |
|
||||
| 12 | [`Nodes_Interface_Architecture_v1.md`](./Nodes_Interface_Architecture_v1.md) | Node dashboards, registration, health, DAGI Mesh |
|
||||
|
||||
---
|
||||
|
||||
## Helper-файли (`helpers/`) — 6
|
||||
|
||||
| Файл | Опис |
|
||||
|------|------|
|
||||
| [`ontology-summary.md`](./helpers/ontology-summary.md) | TL;DR онтології |
|
||||
| [`onboarding-flow-diagram.mermaid`](./helpers/onboarding-flow-diagram.mermaid) | Mermaid-діаграма онбордингу |
|
||||
| [`agent-types-matrix.md`](./helpers/agent-types-matrix.md) | Матриця типів агентів та їх прав |
|
||||
| [`microdao-lifecycle.md`](./helpers/microdao-lifecycle.md) | Життєвий цикл MicroDAO |
|
||||
| [`node-lifecycle.md`](./helpers/node-lifecycle.md) | Життєвий цикл Node |
|
||||
| [`event-schemas.json`](./helpers/event-schemas.json) | JSON Schema для нових подій |
|
||||
|
||||
---
|
||||
|
||||
## Патчі (`patches/`) — 1
|
||||
|
||||
| Файл | Опис |
|
||||
|------|------|
|
||||
| [`DAARION_Person_Agent_DAIS_CoreTeam_PATCH_v1.md`](./patches/DAARION_Person_Agent_DAIS_CoreTeam_PATCH_v1.md) | Human vs Agent, DAIS scope, Core-Team, DAARION108 |
|
||||
|
||||
---
|
||||
|
||||
## Перехресні посилання
|
||||
|
||||
```
|
||||
Онтологія (1)
|
||||
↓
|
||||
Data Model (4) ←→ Event Catalog (5)
|
||||
↓
|
||||
Governance (6) ←→ Identity & Access (7)
|
||||
↓
|
||||
Onboarding (2) → Agents Interface (11) → MicroDAO Interface (9)
|
||||
↓
|
||||
Rooms Layer (8) → City Interface (10) / Nodes Interface (12)
|
||||
```
|
||||
|
||||
### Ключові зв'язки:
|
||||
|
||||
* **Ontology → Data Model → Events** — база для міграцій та синхронізації.
|
||||
* **Onboarding/Identity → Agents → MicroDAO** — шлях користувача від реєстрації до створення DAO.
|
||||
* **Rooms Layer → City/MicroDAO/Agents/Nodes** — визначає UI всіх рівнів.
|
||||
* **Governance → Identity & Access → Nodes** — ACL та інфраструктурні права.
|
||||
* **Patch** — уточнює Human vs Agent та Core-Team model.
|
||||
|
||||
---
|
||||
|
||||
## Використання
|
||||
|
||||
Ці документи є базою для:
|
||||
|
||||
1. **TASK_PHASE_FOUNDATION_UPDATE** — поточна фаза ✅
|
||||
2. **Rooms Layer MVP** — реалізація кімнат
|
||||
3. **City/MicroDAO UI** — інтерфейси
|
||||
4. **DAIS Implementation** — Identity & Access
|
||||
5. **DAGI Mesh** — Node management
|
||||
|
||||
---
|
||||
|
||||
## Task Reference
|
||||
|
||||
📋 [`docs/tasks/TASK_PHASE_FOUNDATION_UPDATE.md`](../tasks/TASK_PHASE_FOUNDATION_UPDATE.md)
|
||||
|
||||
173
docs/foundation/Rooms_Layer_Architecture_v1.md
Normal file
173
docs/foundation/Rooms_Layer_Architecture_v1.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Rooms_Layer_Architecture_v1.md
|
||||
|
||||
## DAARION.city — Rooms Layer & Shared City Space
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Spec (Non-Breaking)
|
||||
**Scope:** City rooms, MicroDAO rooms, District platforms, 2D/3D map, public fronts, inter-DAO interaction
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити, що таке «Кімнати Міста» та загалом Rooms Layer у DAARION.city:
|
||||
|
||||
* як влаштовані простори міста (City Hub, City Square),
|
||||
* як працюють кімнати MicroDAO/District,
|
||||
* як MicroDAO можуть мати публічні front-offices у місті,
|
||||
* як це все відображається в 2D-мапі і майбутньому 3D метавсесвіті,
|
||||
* як Rooms Layer інтегрується з MicroDAO Interface і City Layer.
|
||||
|
||||
---
|
||||
|
||||
# 1. Базова модель
|
||||
|
||||
Rooms Layer працює на трьох рівнях:
|
||||
|
||||
1. **City Hub (root MicroDAO DAARION)** — публічні міські кімнати і фронт-офіси.
|
||||
2. **MicroDAO Space** — внутрішні кімнати, робочі простори, проєкти, core-team.
|
||||
3. **District Space** — платформи, міні-міста з підлеглими MicroDAO.
|
||||
|
||||
Функція Rooms Layer — універсальна: та сама структура для всіх рівнів, але з різним контекстом.
|
||||
|
||||
---
|
||||
|
||||
# 2. Поняття Rooms Layer
|
||||
|
||||
## Room
|
||||
|
||||
* чат / канал / робочий простір;
|
||||
* має `owner_type` (`city | microdao | district | agent`), `owner_id`;
|
||||
* має `space_scope` (`city | microdao | district`);
|
||||
* має `visibility` (`private | members | public-city | public-global`);
|
||||
* опціонально `matrix_room_id`.
|
||||
|
||||
## Location
|
||||
|
||||
* 2D map tile / координати;
|
||||
* 3D anchor (будівля, кіоск);
|
||||
* fallback — список/каталог.
|
||||
|
||||
## Portal
|
||||
|
||||
* кімната-«точка входу» MicroDAO/District у міське середовище;
|
||||
* `is_portal=true`, `portal_target_microdao_id`.
|
||||
|
||||
---
|
||||
|
||||
# 3. Типи кімнат
|
||||
|
||||
1. **City Room** — належить root MicroDAO, `space_scope='city'`.
|
||||
2. **DAO Room** — внутрішні кімнати MicroDAO (`space_scope='microdao'`).
|
||||
3. **Public Front Room** — кімната MicroDAO з `space_scope='city'`.
|
||||
4. **District Room** — кімнати District-платформи (`space_scope='district'`).
|
||||
5. **Agent Room / Booth** — публічні кімнати агентів (Helion, ERP, DARIO).
|
||||
6. **Event Room** — тимчасові/постійні кімнати подій.
|
||||
|
||||
---
|
||||
|
||||
# 4. Модель видимості
|
||||
|
||||
* `owner_type`, `owner_id`.
|
||||
* `visibility`: `private`, `members`, `public-city`, `public-global`.
|
||||
* `space_scope`: `city`, `microdao`, `district`.
|
||||
|
||||
Приклад front-office Energyunion:
|
||||
|
||||
```
|
||||
owner_type = microdao
|
||||
owner_id = energyunion
|
||||
visibility = public-city
|
||||
space_scope = city
|
||||
is_portal = true
|
||||
portal_target_microdao_id = energyunion
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 5. City Hub як спільний простір
|
||||
|
||||
* Місто — місце, де можуть бути присутні всі MicroDAO, District, агенти.
|
||||
* Кожне MicroDAO може зареєструвати портали/кімнати у City Hub.
|
||||
* Публічні агенти (Helion, ERP, DARIO) мають свої кіоски в місті.
|
||||
|
||||
---
|
||||
|
||||
# 6. Інтерфейсні рівні
|
||||
|
||||
## 6.1. City Rooms UI
|
||||
|
||||
* `/city/rooms` — список / карта публічних кімнат.
|
||||
* `/city` — City Square зі слотами кімнат/порталів.
|
||||
* `/city/map` — 2D карта.
|
||||
|
||||
## 6.2. MicroDAO Rooms UI
|
||||
|
||||
* `/microdao/{id}/rooms` — внутрішні кімнати, публікація front-room (прапорець `publish_to_city`).
|
||||
|
||||
## 6.3. District Rooms UI
|
||||
|
||||
* `/district/{id}/rooms` — кімнати платформи, підлеглі DAO.
|
||||
|
||||
---
|
||||
|
||||
# 7. 2D/3D підтримка
|
||||
|
||||
* Кожна кімната може мати `map_x`, `map_y`, `zone`.
|
||||
* 3D-режим використовує `mesh_id`, `3d_position`.
|
||||
* City Square → набір кімнат/порталів, які відображаються як плитки / кіоски.
|
||||
|
||||
---
|
||||
|
||||
# 8. Модель даних (чернетка)
|
||||
|
||||
```sql
|
||||
rooms (
|
||||
id text primary key,
|
||||
owner_type text not null,
|
||||
owner_id text not null,
|
||||
type text not null, -- city-room | dao-room | front-room | agent-room | event-room
|
||||
space_scope text not null, -- city | microdao | district
|
||||
visibility text not null, -- private | members | public-city | public-global
|
||||
matrix_room_id text null,
|
||||
is_portal boolean not null default false,
|
||||
portal_target_microdao_id text null,
|
||||
map_x integer null,
|
||||
map_y integer null,
|
||||
zone text null,
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 9. Governance
|
||||
|
||||
* City rooms створює root MicroDAO або civic-агенти з правами.
|
||||
* DAO rooms створює оркестратор/команда.
|
||||
* Front offices публікує Оркестратор або core-team.
|
||||
* District rooms — оркестратор District.
|
||||
|
||||
---
|
||||
|
||||
# 10. MVP Scope
|
||||
|
||||
* Реєстр City Rooms.
|
||||
* API: `GET /city/rooms`, `GET /city/portals`, `POST /microdao/{id}/rooms`.
|
||||
* Мінімальний UI: список кімнат, дві front-room (Energyunion, GREENFOOD).
|
||||
* Matrix-зв’язок для кімнат.
|
||||
|
||||
---
|
||||
|
||||
# 11. Підсумок
|
||||
|
||||
Rooms Layer уніфікує всі простори DAARION.city:
|
||||
|
||||
* місто як спільний простір,
|
||||
* MicroDAO як власні робочі простори,
|
||||
* District як платформи,
|
||||
* агенти як власники кімнат.
|
||||
|
||||
Це база для 2D/3D DAARION.space.
|
||||
|
||||
213
docs/foundation/Technical_Description_microdao_PATCH_Ontology.md
Normal file
213
docs/foundation/Technical_Description_microdao_PATCH_Ontology.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# Technical_Description_microdao_PATCH_Ontology.md
|
||||
|
||||
## Patch Update: DAARION Ontology, Agent Model, MicroDAO Rules, Node Structure
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Patch Addendum (Non-Breaking Update)
|
||||
**Applies to:** Existing "Технічний опис microdao" документ
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета патча
|
||||
|
||||
Цей документ додає нові архітектурні розділи та уточнення, які:
|
||||
|
||||
* узгоджують microDAO з повною онтологією DAARION.city,
|
||||
* визначають інваріанти Agent/MicroDAO/Node,
|
||||
* вводять механізм Assignment,
|
||||
* уточнюють ролі та типи агентів,
|
||||
* визначають, що District — не нова сутність, а режим MicroDAO,
|
||||
* роблять архітектуру послідовною та розширюваною.
|
||||
|
||||
Патч нічого не ламає в існуючій логіці, лише додає розділи і правила.
|
||||
|
||||
---
|
||||
|
||||
# 1. Новий розділ: «Онтологія DAARION»
|
||||
|
||||
## 1.1. Ієрархія сутностей
|
||||
|
||||
Уся екосистема microdao існує в контексті онтології:
|
||||
|
||||
**Agent → MicroDAO → Node → District**
|
||||
|
||||
Інші об'єкти (канали, кімнати, governance, токени) належать цим сутностям.
|
||||
|
||||
## 1.2. Інваріанти онтології
|
||||
|
||||
* Кожен Agent належить до однієї MicroDAO.
|
||||
* Кожна MicroDAO має одного primary Orchestrator-Agent.
|
||||
* Кожна Node належить конкретній MicroDAO.
|
||||
* District — це режим MicroDAO, а не окремий тип сутності.
|
||||
* У системі не існує «сервісних», «віртуальних» або «нічийних» нод.
|
||||
* Root MicroDAO (DAARION) — предок для всіх MicroDAO.
|
||||
|
||||
---
|
||||
|
||||
# 2. Новий розділ: «Agent Model (оновлений)»
|
||||
|
||||
## 2.1. Базові властивості Agent
|
||||
|
||||
* `agent_id`
|
||||
* `dais_identity_id` (DAIS прив'язка)
|
||||
* `home_microdao_id`
|
||||
* `home_node_id`
|
||||
* `role`: `regular` або `orchestrator`
|
||||
* `service_scope` (нове поле; не обов'язкове)
|
||||
|
||||
## 2.2. Типи агентів
|
||||
|
||||
### A) Personal Agent
|
||||
|
||||
Агент конкретного користувача.
|
||||
Приписаний до MicroDAO (за замовчанням — DAARION).
|
||||
|
||||
### B) Service/Infrastructure Agent
|
||||
|
||||
Агент, який забезпечує роботу сервісів міста.
|
||||
Приписаний до MicroDAO, де він розміщений (частіше — DAARION).
|
||||
Виконується на конкретних нодах.
|
||||
|
||||
### C) Core-City Agent (DAARION108)
|
||||
|
||||
108 агентів-експертів, що працюють для всього міста.
|
||||
`service_scope = "city"`
|
||||
|
||||
### D) Orchestrator Agent
|
||||
|
||||
Агент, що має право створювати MicroDAO.
|
||||
Перехід у Orchestrator створює подію: `agent.promoted_to_orchestrator`.
|
||||
|
||||
---
|
||||
|
||||
# 3. Новий розділ: «MicroDAO (оновлена модель)»
|
||||
|
||||
## 3.1. Структура
|
||||
|
||||
* `microdao_id`
|
||||
* `type`: `root` | `standard` | `district`
|
||||
* `primary_orchestrator_agent_id`
|
||||
* `parent_microdao_id` (для district)
|
||||
* `wallet_address`
|
||||
* `metadata`
|
||||
|
||||
## 3.2. Інваріанти MicroDAO
|
||||
|
||||
* MicroDAO не може існувати без Orchestrator-Agent.
|
||||
* `primary_orchestrator_agent_id` завжди існує і валідний.
|
||||
* Root MicroDAO «DAARION» існує завжди.
|
||||
* District = MicroDAO з розширеними правами.
|
||||
* Усі ноди MicroDAO належать лише їй.
|
||||
|
||||
---
|
||||
|
||||
# 4. Новий розділ: «Node Model»
|
||||
|
||||
## 4.1. Структура ноди
|
||||
|
||||
* `node_id`
|
||||
* `microdao_id`
|
||||
* `node_kind`: `smartphone`, `laptop`, `edge`, `datacenter`, `iot`, `gpu-cluster`
|
||||
* `capabilities` (json)
|
||||
* `status`: `provisioning`, `active`, `draining`, `retired`
|
||||
|
||||
## 4.2. Інваріанти
|
||||
|
||||
* Нода завжди належить MicroDAO.
|
||||
* Немає абстрактних/віртуальних нод.
|
||||
* При реєстрації генерується подія `node.registered`.
|
||||
|
||||
---
|
||||
|
||||
# 5. Новий розділ: «District Model»
|
||||
|
||||
## 5.1. District = MicroDAO з type = district
|
||||
|
||||
Має розширені можливості:
|
||||
|
||||
* керування підлеглими MicroDAO,
|
||||
* право мати власну мережу нод,
|
||||
* роль «платформи» (галузь / район / екосистема).
|
||||
|
||||
## 5.2. Інваріанти District
|
||||
|
||||
* District не змінює власність нод MicroDAO.
|
||||
* District — не новий тип сутності, не нова таблиця.
|
||||
* Перехід MicroDAO → District фіксується подією `microdao.promoted_to_district`.
|
||||
|
||||
---
|
||||
|
||||
# 6. Новий розділ: «Assignment Layer (агенти, які працюють у різних MicroDAO)»
|
||||
|
||||
## 6.1. Призначення
|
||||
|
||||
Деякі агенти можуть:
|
||||
|
||||
* працювати у чужих MicroDAO,
|
||||
* виконувати ролі у District,
|
||||
* діяти від імені міста (DAARION108).
|
||||
|
||||
## 6.2. Структура сутності agent_assignment
|
||||
|
||||
```yaml
|
||||
agent_assignment:
|
||||
id: uuid
|
||||
agent_id: string
|
||||
target_microdao_id: string
|
||||
scope: microdao | district | city
|
||||
role: advisor | security | mentor | ops | core-team
|
||||
start_ts: datetime
|
||||
end_ts: datetime
|
||||
```
|
||||
|
||||
## 6.3. Інваріанти Assignment
|
||||
|
||||
* Assignment не змінює перманентну приписку агента (`home_microdao_id`).
|
||||
* Assignment є записом «тимчасової роботи/сервісу».
|
||||
* DAARION108 мають `scope = city`.
|
||||
|
||||
---
|
||||
|
||||
# 7. Оновлення існуючих розділів документа microdao
|
||||
|
||||
Cursor при інтеграції повинен додати:
|
||||
|
||||
## 7.1. У розділ «Agents»
|
||||
|
||||
* поля: `home_microdao_id`, `home_node_id`, `service_scope`
|
||||
* ролі: `regular`, `orchestrator`
|
||||
* типи агентів (Personal, Service, Core-City)
|
||||
|
||||
## 7.2. У розділ «Teams/MicroDAO»
|
||||
|
||||
* обов'язкове поле `primary_orchestrator_agent_id`
|
||||
* `type = root | standard | district`
|
||||
* `parent_microdao_id`
|
||||
* уточнення про DAARION (root)
|
||||
|
||||
## 7.3. У розділ «Nodes»
|
||||
|
||||
* додати інваріанти
|
||||
* додати типи нод
|
||||
* заборону абстрактних нод
|
||||
|
||||
## 7.4. У розділ «Governance»
|
||||
|
||||
* правило: MicroDAO створюється лише Orchestrator-Agent
|
||||
* District — це не окрема таблиця
|
||||
|
||||
---
|
||||
|
||||
# 8. Підсумок патча
|
||||
|
||||
Після інтеграції цього патча:
|
||||
|
||||
* онтологія DAARION вплетена в microdao,
|
||||
* всі сутності мають однакову семантику в документах та коді,
|
||||
* нові типи агентів (service, core-city) офіційно описані,
|
||||
* модель Assignment додана,
|
||||
* MicroDAO, Node та District узгоджені з фундаментальним баченням,
|
||||
* існуючі системи не змінюються, тільки розширюються.
|
||||
|
||||
Документ №3 завершений.
|
||||
|
||||
274
docs/foundation/User_Onboarding_And_Identity_Layer_v1.md
Normal file
274
docs/foundation/User_Onboarding_And_Identity_Layer_v1.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# User_Onboarding_And_Identity_Layer_v1.md
|
||||
|
||||
## DAARION.city — User Onboarding & Identity Layer (DAIS)
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Core Spec (Foundation Update)
|
||||
**Scope:** Реєстрація користувача, створення агентів, DAIS, wallet-логін, Orchestrator, MicroDAO
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Цей документ описує **повний процес онбордингу користувача** в DAARION.city:
|
||||
|
||||
* реєстрацію → DAIS-профіль → Agent → Orchestrator → MicroDAO;
|
||||
* Email-OTP та Magic Link;
|
||||
* Web3 Wallet login та SIWE;
|
||||
* правила доступу, ролі та підвищення;
|
||||
* зберігання та синхронізацію ідентичностей;
|
||||
* формування кабінету агента;
|
||||
* перевірку токенів та прав на створення MicroDAO.
|
||||
|
||||
Документ створено як **неламке оновлення архітектури (non-breaking)**.
|
||||
|
||||
---
|
||||
|
||||
# 1. Загальний огляд онбордингу
|
||||
|
||||
Онбординг DAARION.city складається з трьох рівнів:
|
||||
|
||||
1. **DAIS Identity Layer**
|
||||
— email, wallet, DID, keys → єдиний цифровий профіль.
|
||||
|
||||
2. **Agent Creation Layer**
|
||||
— автоматичне створення агента + кабінету при першій реєстрації.
|
||||
|
||||
3. **Orchestrator → MicroDAO Layer**
|
||||
— підвищення агента + створення MicroDAO за умовами доступу.
|
||||
|
||||
Це забезпечує інтуїтивний UX та жорстку архітектурну дисципліну.
|
||||
|
||||
---
|
||||
|
||||
# 2. DAIS Identity Layer
|
||||
|
||||
DAIS = **DAARION Autonomous Identity System**.
|
||||
Це єдиний простір ідентифікації для людей, агентів і MicroDAO.
|
||||
|
||||
## 2.1. Структура DAIS-ідентичності
|
||||
|
||||
DAIS-ідентичність містить:
|
||||
|
||||
* **email-identities** (1..N)
|
||||
* **wallet-identities** (EVM / SIWE)
|
||||
* **telegram / TON identities** (майбутнє)
|
||||
* **DID / Matrix identity**
|
||||
* **public keys** (Ed25519 / secp256k1 / X25519)
|
||||
* **signature domains** (підписи для сервісів)
|
||||
* **recovery options**
|
||||
|
||||
## 2.2. Інваріанти DAIS
|
||||
|
||||
1. Один користувач = одна DAIS-ідентичність.
|
||||
2. DAIS-профіль може мати багато email'ів і багато wallet'ів.
|
||||
3. DAIS-профіль створюється **до** створення агента.
|
||||
4. DAIS-профіль не може бути видалений, тільки ротується/оновлюється.
|
||||
|
||||
---
|
||||
|
||||
# 3. Реєстрація та автентифікація
|
||||
|
||||
DAARION.city підтримує два базові методи входу:
|
||||
|
||||
## 3.1. Email-OTP (One-Time Password)
|
||||
|
||||
Флоу:
|
||||
|
||||
1. Користувач вводить email.
|
||||
2. Отримує одноразовий код (OTP).
|
||||
3. Підтверджує код.
|
||||
4. Створюється/активується DAIS-profile.
|
||||
5. Створюється Agent + кабінет.
|
||||
|
||||
Переваги:
|
||||
|
||||
* Zero-password.
|
||||
* Найменший бар'єр входу.
|
||||
* Підходить для всіх типів користувачів.
|
||||
|
||||
## 3.2. Magic Link
|
||||
|
||||
Флоу:
|
||||
|
||||
1. Користувач вводить email.
|
||||
2. Отримує магічне посилання.
|
||||
3. Перехід → автоматичний вхід.
|
||||
4. Створюється DAIS-profile → Agent.
|
||||
|
||||
## 3.3. Web3 Wallet Login (SIWE)
|
||||
|
||||
Підтримка: MetaMask, Rabby, WalletConnect.
|
||||
|
||||
Флоу:
|
||||
|
||||
1. Користувач підключає EVM-гаманець.
|
||||
2. Підписує SIWE-повідомлення.
|
||||
3. Створюється/активується DAIS-profile.
|
||||
4. Гаманець стає частиною DAIS-ідентичності.
|
||||
5. Створюється Agent.
|
||||
|
||||
## 3.4. Синхронізація Email + Wallet
|
||||
|
||||
Будь-який окремий метод додає ідентичність у DAIS.
|
||||
При об'єднанні email і wallet → DAIS залишається єдиною сутністю.
|
||||
|
||||
---
|
||||
|
||||
# 4. Створення Агентів (Agent Creation Layer)
|
||||
|
||||
## 4.1. Коли створюється Agent
|
||||
|
||||
Agent створюється автоматично при:
|
||||
|
||||
* першому вході через email OTP,
|
||||
* або першій верифікованій SIWE-сесії,
|
||||
* або при Telegram/TON-верифікації в майбутньому.
|
||||
|
||||
## 4.2. Агент отримує:
|
||||
|
||||
* `agent_id`
|
||||
* `home_microdao_id = DAARION (root)`
|
||||
* `home_node_id = DAARION-root-node`
|
||||
* DAIS-прив'язку
|
||||
* Кабінет агента
|
||||
* Роль: `regular`
|
||||
|
||||
## 4.3. Кабінет агента включає:
|
||||
|
||||
* Wallet overview
|
||||
* Email overview
|
||||
* Agent avatar / profile
|
||||
* Список підключених нод
|
||||
* Доступні сервіси
|
||||
* Статус до MicroDAO
|
||||
* Кнопку «Стати Оркестратором»
|
||||
|
||||
---
|
||||
|
||||
# 5. Перехід у Orchestrator (Orchestrator Promotion)
|
||||
|
||||
Це ключовий момент.
|
||||
|
||||
Користувач **не може** створити MicroDAO, поки:
|
||||
|
||||
* не має агента,
|
||||
* не має оркестраторської ролі,
|
||||
* не виконав умови допуску.
|
||||
|
||||
## 5.1. Флоу переходу
|
||||
|
||||
1. Користувач натискає «Стати Оркестратором».
|
||||
2. Система перевіряє **умови доступу**.
|
||||
3. Якщо всі умови виконано → підвищення агента.
|
||||
4. Генерується подія `agent.promoted_to_orchestrator`.
|
||||
5. Роль агента = `orchestrator`.
|
||||
6. Відкривається Wizard створення MicroDAO.
|
||||
|
||||
## 5.2. Умови допуску
|
||||
|
||||
Умови встановлюються governance DAARION і можуть включати:
|
||||
|
||||
* прив'язаний Web3-гаманець;
|
||||
* наявність основного токена (DAAR / DAARION);
|
||||
* спеціальний NFT (Founder / Builder / Citizen);
|
||||
* підтверджений email (обов'язково);
|
||||
* мінімальний рівень довіри DAIS;
|
||||
* проста верифікація через Matrix/Telegram.
|
||||
|
||||
## 5.3. Інваріанти Orchestrator
|
||||
|
||||
1. Кожен Orchestrator — це Agent, але не кожен Agent є Orchestrator.
|
||||
2. Підвищення — це **одна подія** на агент (необоротна, але можна «заморозити» вручну).
|
||||
3. Orchestrator може створити багато MicroDAO.
|
||||
|
||||
---
|
||||
|
||||
# 6. Створення MicroDAO
|
||||
|
||||
Коли агент стає Orchestrator → доступний Wizard створення MicroDAO.
|
||||
|
||||
## 6.1. Флоу
|
||||
|
||||
1. Старт Wizard: назва, опис, цілі, аватар.
|
||||
2. Прив'язка DAIS-гаманця MicroDAO.
|
||||
3. Створення запису `microdao_id`.
|
||||
4. `primary_orchestrator_agent_id = цей агент`.
|
||||
5. Ініціалізація governance.
|
||||
6. Створення простору MicroDAO (канали, кімнати).
|
||||
7. Генерується подія `microdao.created`.
|
||||
8. Користувач переходить у кабінет MicroDAO.
|
||||
|
||||
## 6.2. Інваріанти MicroDAO в онбордингу
|
||||
|
||||
1. Немає MicroDAO без Orchestrator-Agent.
|
||||
2. MicroDAO створюється саме в момент запуску Wizard, а не раніше.
|
||||
3. Доступ до створення MicroDAO має лише Orchestrator.
|
||||
|
||||
---
|
||||
|
||||
# 7. Після створення MicroDAO: реєстрація нод
|
||||
|
||||
MicroDAO одразу отримує можливість:
|
||||
|
||||
* реєструвати ноди,
|
||||
* прив'язувати пристрої,
|
||||
* запускати сервісних агентів.
|
||||
|
||||
Флоу:
|
||||
|
||||
1. Orchestrator заходить у MicroDAO → Nodes.
|
||||
2. Обирає «Зареєструвати Ноду».
|
||||
3. Тип ноди: смартфон, ноут, сервер, IoT, GPU-кластер.
|
||||
4. Автентифікація через DAIS-ключ.
|
||||
5. Створюється запис `node_id`.
|
||||
6. Генерується подія `node.registered`.
|
||||
|
||||
---
|
||||
|
||||
# 8. Значення онбордингу для онтології
|
||||
|
||||
Оновлений онбординг:
|
||||
|
||||
* **повністю відповідає онтології** Agent → MicroDAO → Node → District
|
||||
* не ламає поточний UI (кнопка «Створити MicroDAO» зберігається)
|
||||
* додає строгий порядок:
|
||||
|
||||
1. DAIS Identity
|
||||
2. Agent
|
||||
3. Orchestrator
|
||||
4. MicroDAO
|
||||
5. Node
|
||||
6. District (опційно)
|
||||
|
||||
---
|
||||
|
||||
# 9. Події Stream (NATS)
|
||||
|
||||
Під час онбордингу фіксуються ключові події:
|
||||
|
||||
1. `dais.identity_created`
|
||||
2. `agent.created`
|
||||
3. `agent.promoted_to_orchestrator`
|
||||
4. `microdao.created`
|
||||
5. `node.registered`
|
||||
6. (опційно) `microdao.promoted_to_district`
|
||||
|
||||
---
|
||||
|
||||
# 10. Резюме
|
||||
|
||||
Оновлений онбординг DAARION забезпечує:
|
||||
|
||||
* єдину ідентичність DAIS
|
||||
* автоматичне створення агента
|
||||
* чіткі умови доступу для Orchestrator
|
||||
* чисту модель MicroDAO
|
||||
* логічний шлях до реєстрації нод
|
||||
* сумісність з майбутнім District Layer
|
||||
* UX, що не ламає існуючих сценаріїв
|
||||
|
||||
---
|
||||
|
||||
Документ №2 завершено.
|
||||
|
||||
10
docs/foundation/helpers/agent-types-matrix.md
Normal file
10
docs/foundation/helpers/agent-types-matrix.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Agent Types Matrix
|
||||
|
||||
| Тип агента | Опис | Приписка | Scope | Може створити MicroDAO | Може працювати у чужих MicroDAO |
|
||||
|------------|------|----------|--------|-------------------------|---------------------------------|
|
||||
| Personal Agent | Агент користувача | обов'язково (до DAARION) | microdao | ні | через assignment |
|
||||
| Service Agent | Технічний агент | до MicroDAO, де розгорнутий | microdao / district | ні | так, якщо assignment |
|
||||
| Infrastructure Agent | gateway/bridge/monitor | DAARION | district/city | ні | так |
|
||||
| Core-City Agent (DAARION108) | міська команда | DAARION | city | ні | так (auto) |
|
||||
| Orchestrator Agent | має доступ до створення MicroDAO | своя MicroDAO | microdao | **так** | ні |
|
||||
|
||||
41
docs/foundation/helpers/event-schemas.json
Normal file
41
docs/foundation/helpers/event-schemas.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"agent.promoted_to_orchestrator": {
|
||||
"agent_id": "string",
|
||||
"timestamp": "datetime"
|
||||
},
|
||||
"microdao.created": {
|
||||
"microdao_id": "string",
|
||||
"primary_orchestrator_agent_id": "string",
|
||||
"type": "root | standard | district",
|
||||
"parent_microdao_id": "string|null",
|
||||
"timestamp": "datetime"
|
||||
},
|
||||
"node.registered": {
|
||||
"node_id": "string",
|
||||
"microdao_id": "string",
|
||||
"node_kind": "smartphone|laptop|edge|datacenter|iot|gpu-cluster",
|
||||
"capabilities": "object",
|
||||
"timestamp": "datetime"
|
||||
},
|
||||
"microdao.promoted_to_district": {
|
||||
"microdao_id": "string",
|
||||
"promoted_by_agent_id": "string",
|
||||
"parent_microdao_id": "string",
|
||||
"timestamp": "datetime"
|
||||
},
|
||||
"agent.assignment_created": {
|
||||
"assignment_id": "string",
|
||||
"agent_id": "string",
|
||||
"target_microdao_id": "string",
|
||||
"scope": "microdao|district|city",
|
||||
"role": "string",
|
||||
"metadata": "object",
|
||||
"timestamp": "datetime"
|
||||
},
|
||||
"agent.assignment_ended": {
|
||||
"assignment_id": "string",
|
||||
"agent_id": "string",
|
||||
"timestamp": "datetime"
|
||||
}
|
||||
}
|
||||
|
||||
16
docs/foundation/helpers/microdao-lifecycle.md
Normal file
16
docs/foundation/helpers/microdao-lifecycle.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# MicroDAO Lifecycle
|
||||
|
||||
1. Agent creates DAIS Identity
|
||||
2. Agent is created (home = DAARION)
|
||||
3. Agent becomes Orchestrator
|
||||
4. Orchestrator runs MicroDAO Creation Wizard
|
||||
5. `microdao.created` event emitted
|
||||
6. MicroDAO governance initialized
|
||||
7. Orchestrator registers nodes
|
||||
8. `node.registered` events emitted
|
||||
9. MicroDAO grows (members, rooms, agents)
|
||||
10. (optional) MicroDAO promoted to District
|
||||
11. `microdao.promoted_to_district` event
|
||||
12. District manages sub-MicroDAO network
|
||||
13. MicroDAO can be archived (future)
|
||||
|
||||
13
docs/foundation/helpers/node-lifecycle.md
Normal file
13
docs/foundation/helpers/node-lifecycle.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Node Lifecycle
|
||||
|
||||
1. Orchestrator triggers "Register Node"
|
||||
2. Device generates DAIS node-auth key
|
||||
3. MicroDAO verifies key ownership
|
||||
4. `node.registered` event emitted
|
||||
5. Node enters "provisioning" state
|
||||
6. Agent workers start connecting
|
||||
7. Node becomes "active"
|
||||
8. Node can be updated (capabilities change)
|
||||
9. Node enters "draining" before shutdown
|
||||
10. Node becomes "retired"
|
||||
|
||||
18
docs/foundation/helpers/onboarding-flow-diagram.mermaid
Normal file
18
docs/foundation/helpers/onboarding-flow-diagram.mermaid
Normal file
@@ -0,0 +1,18 @@
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[User visits DAARION.city] --> B{Login method}
|
||||
B -->|Email OTP| C[Create/Activate DAIS Identity]
|
||||
B -->|Magic Link| C
|
||||
B -->|Web3 Wallet (SIWE)| C
|
||||
C --> D[Create Agent (home_microdao = DAARION)]
|
||||
D --> E[Agent Console]
|
||||
E --> F{Become Orchestrator?}
|
||||
F -->|Yes| G[Check Access Conditions (wallet, tokens)]
|
||||
G -->|Pass| H[agent.promoted_to_orchestrator]
|
||||
H --> I[MicroDAO Creation Wizard]
|
||||
I --> J[microdao.created]
|
||||
J --> K[NODE REGISTRATION]
|
||||
K --> L[node.registered]
|
||||
L --> M[MicroDAO Operational]
|
||||
```
|
||||
|
||||
47
docs/foundation/helpers/ontology-summary.md
Normal file
47
docs/foundation/helpers/ontology-summary.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# DAARION Ontology — TL;DR
|
||||
|
||||
## 1. Основна лінія походження
|
||||
|
||||
`Agent → MicroDAO → Node → District`
|
||||
|
||||
## 2. Визначення сутностей
|
||||
|
||||
### Agent
|
||||
|
||||
* персональний або сервісний ШІ-агент;
|
||||
* має DAIS-ідентичність (email + wallet + DID);
|
||||
* завжди приписаний до `home_microdao_id`;
|
||||
* має `role: regular | orchestrator`;
|
||||
* має `service_scope: microdao | district | city`.
|
||||
|
||||
### MicroDAO
|
||||
|
||||
* мікро-спільнота, команда або проєкт;
|
||||
* типи: `root`, `standard`, `district`;
|
||||
* має `primary_orchestrator_agent_id`;
|
||||
* може мати ноди;
|
||||
* може бути підвищена до District.
|
||||
|
||||
### Node
|
||||
|
||||
* реальний пристрій (smartphone, laptop, edge, datacenter, iot, gpu-cluster);
|
||||
* завжди належить MicroDAO (`microdao_id`);
|
||||
* має `capabilities`, `status`.
|
||||
|
||||
### District
|
||||
|
||||
* MicroDAO з `type = district`;
|
||||
* має розширені повноваження для підлеглих MicroDAO;
|
||||
* керує підмережами нод.
|
||||
|
||||
## 3. Assignment Layer
|
||||
|
||||
Описує, де агент *працює*, не змінюючи приписку.
|
||||
|
||||
Поля:
|
||||
|
||||
* `agent_id`
|
||||
* `target_microdao_id`
|
||||
* `scope` (`microdao` \| `district` \| `city`)
|
||||
* `role` (`advisor` \| `ops` \| `security` \| `mentor` \| `core-team`)
|
||||
|
||||
239
docs/foundation/microdao_Data_Model_UPDATE_v1.md
Normal file
239
docs/foundation/microdao_Data_Model_UPDATE_v1.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# microdao_Data_Model_UPDATE_v1.md
|
||||
|
||||
## microDAO — Data Model Update (Foundation Layer)
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Non-Breaking Schema Extension
|
||||
**Scope:** agents, microdaos, nodes, assignments, capabilities, metadata
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Цей документ визначає оновлену модель даних microDAO, яка:
|
||||
|
||||
* формалізує онтологію DAARION (Agent → MicroDAO → Node → District),
|
||||
* вводить нові інваріанти,
|
||||
* додає нові сутності та поля,
|
||||
* стандартизує JSON-поля `capabilities` і `metadata`,
|
||||
* додає шар Assignment для агента, який працює в інших MicroDAO,
|
||||
* залишається сумісною з існуючою системою (non-breaking).
|
||||
|
||||
---
|
||||
|
||||
# 1. Загальна структура моделі
|
||||
|
||||
Оновлена модель складається з п’яти головних сутностей:
|
||||
|
||||
1. `agents` (оновлено)
|
||||
2. `microdaos` (оновлено)
|
||||
3. `nodes` (оновлено)
|
||||
4. `agent_assignments` (нова таблиця)
|
||||
5. `event_log` / outbox (оновлено відповідно до подій)
|
||||
|
||||
Усі ці сутності підтримують фундаментальну онтологію DAARION.
|
||||
|
||||
---
|
||||
|
||||
# 2. Таблиця `agents` (оновлена)
|
||||
|
||||
Призначення: зберігати всіх агентів міста — персональних, сервісних, інфраструктурних, core-city, orchestrator.
|
||||
|
||||
## 2.1. Поля
|
||||
|
||||
```sql
|
||||
agents (
|
||||
id text primary key,
|
||||
dais_identity_id text not null,
|
||||
|
||||
-- базова приписка
|
||||
home_microdao_id text not null references microdaos(id),
|
||||
home_node_id text null references nodes(id),
|
||||
|
||||
-- роль агента
|
||||
role text not null check (role in ('regular','orchestrator')),
|
||||
|
||||
-- тип діяльності (розширений шар)
|
||||
service_scope text null
|
||||
check (service_scope in ('microdao','district','city')),
|
||||
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
```
|
||||
|
||||
## 2.2. Опис ключових полів
|
||||
|
||||
* `home_microdao_id` — база агента (жорсткий інваріант).
|
||||
* `home_node_id` — нода, на якій живе агент (може бути null).
|
||||
* `role` — `regular` або `orchestrator`.
|
||||
* `service_scope` — `microdao`, `district`, `city`.
|
||||
* `metadata` — додаткові параметри (аватар, worker-конфіги, теги тощо).
|
||||
|
||||
---
|
||||
|
||||
# 3. Таблиця `microdaos` (оновлена)
|
||||
|
||||
Призначення: зберігати root, standard, district MicroDAO.
|
||||
|
||||
## 3.1. Поля
|
||||
|
||||
```sql
|
||||
microdaos (
|
||||
id text primary key,
|
||||
|
||||
type text not null
|
||||
check (type in ('root','standard','district')),
|
||||
|
||||
primary_orchestrator_agent_id text not null
|
||||
references agents(id),
|
||||
|
||||
parent_microdao_id text null references microdaos(id),
|
||||
|
||||
wallet_address text null,
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
```
|
||||
|
||||
## 3.2. Інваріанти
|
||||
|
||||
* MicroDAO не може існувати без `primary_orchestrator_agent_id`.
|
||||
* `type='root'` зарезервовано для DAARION.
|
||||
* `type='district'` дає розширені можливості.
|
||||
* МікроДАО можуть формувати дерево через `parent_microdao_id`.
|
||||
|
||||
---
|
||||
|
||||
# 4. Таблиця `nodes` (оновлена)
|
||||
|
||||
Призначення: зберігати фізичні / логічні вузли виконання DAGI Mesh.
|
||||
|
||||
## 4.1. Поля
|
||||
|
||||
```sql
|
||||
nodes (
|
||||
id text primary key,
|
||||
|
||||
microdao_id text not null references microdaos(id),
|
||||
|
||||
node_kind text not null
|
||||
check (node_kind in (
|
||||
'smartphone','laptop','edge','datacenter',
|
||||
'iot','gpu-cluster'
|
||||
)),
|
||||
|
||||
capabilities jsonb not null default '{}'::jsonb,
|
||||
|
||||
status text not null
|
||||
check (status in ('provisioning','active','draining','retired')),
|
||||
|
||||
metadata jsonb not null default '{}'::jsonb,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
```
|
||||
|
||||
## 4.2. Інваріанти
|
||||
|
||||
* Node завжди належить конкретній MicroDAO.
|
||||
* Node — реальний пристрій (не абстракція).
|
||||
* При створенні ноди генерується подія `node.registered`.
|
||||
|
||||
---
|
||||
|
||||
# 5. Таблиця `agent_assignments` (нова)
|
||||
|
||||
Призначення: описує, де агент працює (service layer), не змінюючи приписку.
|
||||
|
||||
## 5.1. Поля
|
||||
|
||||
```sql
|
||||
agent_assignments (
|
||||
id uuid primary key,
|
||||
|
||||
agent_id text not null references agents(id),
|
||||
target_microdao_id text not null references microdaos(id),
|
||||
|
||||
scope text not null
|
||||
check (scope in ('microdao','district','city')),
|
||||
|
||||
role text not null, -- advisor/security/mentor/ops/core-team
|
||||
|
||||
start_ts timestamptz not null default now(),
|
||||
end_ts timestamptz null,
|
||||
|
||||
metadata jsonb not null default '{}'::jsonb
|
||||
);
|
||||
```
|
||||
|
||||
## 5.2. Інваріанти
|
||||
|
||||
* Assignment не змінює `home_microdao_id`.
|
||||
* DAARION108 мають assignments з `scope='city'`.
|
||||
* Service/Infrastructure агенти можуть мати кілька assignments.
|
||||
|
||||
---
|
||||
|
||||
# 6. JSON-структури
|
||||
|
||||
## 6.1. `capabilities.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"cpu": "8 cores",
|
||||
"ram": "32GB",
|
||||
"gpu": {
|
||||
"model": "RTX 4090",
|
||||
"vram": "24GB"
|
||||
},
|
||||
"network": {
|
||||
"up": "1Gbps",
|
||||
"down": "1Gbps"
|
||||
},
|
||||
"sensors": ["camera","lidar","temperature"]
|
||||
}
|
||||
```
|
||||
|
||||
## 6.2. `metadata.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"agent_type": "service",
|
||||
"citywide": true,
|
||||
"labels": ["core","secure","production"],
|
||||
"notes": "This agent is part of DAARION108"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. Події (пов’язані з моделлю)
|
||||
|
||||
* `agent.promoted_to_orchestrator`
|
||||
* `microdao.created`
|
||||
* `node.registered`
|
||||
* `microdao.promoted_to_district`
|
||||
* `agent.assignment_created`
|
||||
* `agent.assignment_ended`
|
||||
|
||||
Їхні схеми визначені в `microdao_Event_Catalog_EXTENDED_v1.md`.
|
||||
|
||||
---
|
||||
|
||||
# 8. Міграції (чорновий план)
|
||||
|
||||
* додати поля до `agents`;
|
||||
* додати поля до `microdaos`;
|
||||
* оновити `nodes`;
|
||||
* створити `agent_assignments`;
|
||||
* додати enum-типи (за потреби).
|
||||
|
||||
---
|
||||
|
||||
# 9. Підсумок
|
||||
|
||||
Модель даних тепер повністю відповідає фундаментальній онтології DAARION.
|
||||
Усі інваріанти формалізовані, Assignment layer додано, структури capabilities/metadata стандартизовано.
|
||||
Документ готовий до реалізації міграцій та оновлень у коді.
|
||||
|
||||
236
docs/foundation/microdao_Event_Catalog_EXTENDED_v1.md
Normal file
236
docs/foundation/microdao_Event_Catalog_EXTENDED_v1.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# microdao_Event_Catalog_EXTENDED_v1.md
|
||||
|
||||
## DAARION.city — Event Catalog (Extended Ontology Update)
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Core Spec Update (Non-Breaking)
|
||||
**Scope:** Agent → Orchestrator → MicroDAO → Node → District → Assignment
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити повний перелік нових доменних подій, які:
|
||||
|
||||
* підтримують онтологію DAARION (Agent → MicroDAO → Node → District),
|
||||
* описують життєвий цикл агента, мікроДАО, нод та assignment layer,
|
||||
* забезпечують єдиний контракт для NATS Stream та DAGI Router.
|
||||
|
||||
Document не змінює існуючі події microdao — лише додає нові.
|
||||
|
||||
---
|
||||
|
||||
# 1. Стандарти подій
|
||||
|
||||
## 1.1. Структурні правила
|
||||
|
||||
* формат JSON;
|
||||
* поле `event_id` (uuid v4);
|
||||
* поле `timestamp` (ISO8601 UTC);
|
||||
* поле `version` (semver);
|
||||
* поле `subject` (назва події);
|
||||
* поле `payload` (дані події).
|
||||
|
||||
## 1.2. Транспортування
|
||||
|
||||
Події транспортуються через NATS у форматі:
|
||||
|
||||
`dagion.<domain>.<event>`
|
||||
|
||||
---
|
||||
|
||||
# 2. Нові події онтології DAARION
|
||||
|
||||
## 2.1. `agent.promoted_to_orchestrator`
|
||||
|
||||
* **NATS subject:** `dagion.agent.promoted_to_orchestrator`
|
||||
* **Опис:** Агент отримує роль Orchestrator.
|
||||
* **Payload:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["agent_id","timestamp"],
|
||||
"properties": {
|
||||
"agent_id": { "type": "string" },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2.2. `microdao.created`
|
||||
|
||||
* **Subject:** `dagion.microdao.created`
|
||||
* **Опис:** Створено нову MicroDAO.
|
||||
* **Payload:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"microdao_id",
|
||||
"primary_orchestrator_agent_id",
|
||||
"type",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"microdao_id": { "type": "string" },
|
||||
"primary_orchestrator_agent_id": { "type": "string" },
|
||||
"type": { "type": "string", "enum": ["root","standard","district"] },
|
||||
"parent_microdao_id": { "type": ["string","null"] },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2.3. `node.registered`
|
||||
|
||||
* **Subject:** `dagion.node.registered`
|
||||
* **Опис:** Зареєстрована нова нода.
|
||||
* **Payload:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"node_id",
|
||||
"microdao_id",
|
||||
"node_kind",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"node_id": { "type": "string" },
|
||||
"microdao_id": { "type": "string" },
|
||||
"node_kind": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"smartphone","laptop","edge",
|
||||
"datacenter","iot","gpu-cluster"
|
||||
]
|
||||
},
|
||||
"capabilities": { "type": "object" },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2.4. `microdao.promoted_to_district`
|
||||
|
||||
* **Subject:** `dagion.microdao.promoted_to_district`
|
||||
* **Опис:** MicroDAO отримує статус District.
|
||||
* **Payload:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"microdao_id",
|
||||
"promoted_by_agent_id",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"microdao_id": { "type": "string" },
|
||||
"promoted_by_agent_id": { "type": "string" },
|
||||
"parent_microdao_id": { "type": "string" },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 3. Assignment Layer Events
|
||||
|
||||
## 3.1. `agent.assignment_created`
|
||||
|
||||
* **Subject:** `dagion.agent.assignment_created`
|
||||
* **Опис:** Агент отримав роль у іншій MicroDAO/District/City.
|
||||
* **Payload:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"assignment_id",
|
||||
"agent_id",
|
||||
"target_microdao_id",
|
||||
"scope",
|
||||
"role",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"assignment_id": { "type": "string" },
|
||||
"agent_id": { "type": "string" },
|
||||
"target_microdao_id": { "type": "string" },
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"enum": ["microdao","district","city"]
|
||||
},
|
||||
"role": { "type": "string" },
|
||||
"metadata": { "type": "object" },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3.2. `agent.assignment_ended`
|
||||
|
||||
* **Subject:** `dagion.agent.assignment_ended`
|
||||
* **Опис:** Завершено assignment агента.
|
||||
* **Payload:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"assignment_id",
|
||||
"agent_id",
|
||||
"timestamp"
|
||||
],
|
||||
"properties": {
|
||||
"assignment_id": { "type": "string" },
|
||||
"agent_id": { "type": "string" },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4. Події ідентичності (довідково)
|
||||
|
||||
Зовнішній Identity Service генерує:
|
||||
|
||||
* `dais.identity_created` (`dagion.identity.created`)
|
||||
* `agent.created` (`dagion.agent.created`)
|
||||
|
||||
Ці події використовуються microdao для синхронізації.
|
||||
|
||||
---
|
||||
|
||||
# 5. Зв’язок подій з життєвими циклами
|
||||
|
||||
* **Agent lifecycle:** `identity.created → agent.created → agent.promoted_to_orchestrator → assignment events`.
|
||||
* **MicroDAO lifecycle:** `agent.promoted_to_orchestrator → microdao.created → microdao.promoted_to_district`.
|
||||
* **Node lifecycle:** `microdao.created → node.registered`.
|
||||
|
||||
---
|
||||
|
||||
# 6. Гарантії та інваріанти
|
||||
|
||||
* Події не відкатуються.
|
||||
* Кожна подія має `event_id`, `timestamp`, `version`.
|
||||
* Подія не може суперечити онтології DAARION.
|
||||
* Payload завжди відповідає цій моделі даних.
|
||||
|
||||
---
|
||||
|
||||
# 7. Переваги Extended Event Catalog
|
||||
|
||||
* Повний опис життєвих циклів Agent/MicroDAO/Node/District.
|
||||
* Синхронізація Identity, microdao, Gateway, DAGI Router.
|
||||
* Автоматичні реакції agents-as-workers.
|
||||
* Підготовка до наступних фаз governance та city automation.
|
||||
|
||||
Документ завершено.
|
||||
|
||||
145
docs/foundation/microdao_Governance_And_Permissions_v1.md
Normal file
145
docs/foundation/microdao_Governance_And_Permissions_v1.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# microdao_Governance_And_Permissions_v1.md
|
||||
|
||||
## DAARION.city — Governance & Permissions Layer (Minimal Core)
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Foundation Spec (Non-Breaking)
|
||||
**Scope:** Agents, Orchestrators, MicroDAO, Nodes, Districts
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета документа
|
||||
|
||||
Визначити мінімальну, але строгу модель управління та доступів у DAARION.city, яка:
|
||||
|
||||
* відповідає онтології Agent → MicroDAO → Node → District,
|
||||
* захищає критичні операції (створення MicroDAO, реєстрація нод, assignments),
|
||||
* визначає ролі та ACL, не вводячи громіздкого DAO-протоколу.
|
||||
|
||||
Документ розширює існуючі правила microdao без змін поведінки.
|
||||
|
||||
---
|
||||
|
||||
# 1. Принципи Governance DAARION
|
||||
|
||||
1. **Примат онтології.** Усі правила походять із структури Agent → MicroDAO → Node → District.
|
||||
2. **Мінімальна достатність.** На базовому етапі — тільки найнеобхідніші механіки.
|
||||
3. **Безпека через приписку.** Будь-який агент/нода мають формальну MicroDAO-приписку.
|
||||
4. **DAARION як root governance.** Root MicroDAO — вища інстанція та еталон.
|
||||
|
||||
---
|
||||
|
||||
# 2. Ролі агентів
|
||||
|
||||
| Роль | Опис | Доступи |
|
||||
|-----------------|-------------------------------------------------------------|-----------------------------------------------------------|
|
||||
| Regular Agent | стандартний агент | вхід, участь у сервісах, виконання assignment |
|
||||
| Orchestrator | агент, що керує MicroDAO | створення MicroDAO, управління нодами, членами |
|
||||
| Service Agent | технічний/сервісний агент | доступ до внутрішньої інфраструктури |
|
||||
| Core-City Agent | DAARION108 (citywide scope) | робота в усьому місті (при дотриманні політик) |
|
||||
|
||||
---
|
||||
|
||||
# 3. Governance MicroDAO
|
||||
|
||||
## 3.1. Основні артефакти
|
||||
|
||||
* `primary_orchestrator_agent_id`
|
||||
* склад агентів і людей
|
||||
* ноди
|
||||
* assignments інших агентів
|
||||
* DAO-налаштування
|
||||
|
||||
## 3.2. Дозволи (мінімальний набір)
|
||||
|
||||
* Оркестратор:
|
||||
* редагування `metadata`
|
||||
* додавання учасників
|
||||
* запрошення агентів
|
||||
* реєстрація / вимикання нод
|
||||
* налаштування front-office
|
||||
* підвищення до District
|
||||
* Члени:
|
||||
* доступ до DAO-кімнат
|
||||
* участь у проектах
|
||||
* запуск власних агентів (за правилами governance)
|
||||
|
||||
---
|
||||
|
||||
# 4. Node Governance
|
||||
|
||||
* **Хто реєструє ноду?** Оркестратор MicroDAO.
|
||||
* **Хто керує нодою?** Оркестратор + довірені core-team агенти (Node Manager, DevOps).
|
||||
* **Хто може використовувати ноду?**
|
||||
* агенти цього MicroDAO
|
||||
* агенти з assignment (якщо дозволено governance)
|
||||
* citywide агенти (DAARION108) — тільки при спец-дозволах.
|
||||
|
||||
---
|
||||
|
||||
# 5. District Governance
|
||||
|
||||
District = MicroDAO `type='district'`.
|
||||
|
||||
Особливості:
|
||||
|
||||
* може мати `parent_microdao_id`;
|
||||
* керує пулом підлеглих MicroDAO;
|
||||
* має власні ноди / платформи;
|
||||
* може координувати між-DAO задачі;
|
||||
* перехід фіксується подією `microdao.promoted_to_district`.
|
||||
|
||||
---
|
||||
|
||||
# 6. Assignment Governance
|
||||
|
||||
Assignment дозволяє агенту працювати поза `home_microdao_id`.
|
||||
|
||||
* **Хто створює assignment?**
|
||||
* Оркестратор MicroDAO (який приймає агента),
|
||||
* District (для своїх підлеглих),
|
||||
* DAARION (root) — для citywide операцій.
|
||||
* **Для чого:**
|
||||
* DAARION108 → citywide tasks,
|
||||
* сервісні агенти → підтримка інших MicroDAO,
|
||||
* зовнішні експерти → консалтинг/безпека.
|
||||
* **Події:** `agent.assignment_created`, `agent.assignment_ended`.
|
||||
|
||||
---
|
||||
|
||||
# 7. ACL-модель (мінімум)
|
||||
|
||||
| Дозвіл | Опис | Хто має |
|
||||
|--------------------|-------------------------------------|---------------------|
|
||||
| `CREATE_MICRODAO` | Створити MicroDAO | Orchestrator |
|
||||
| `REGISTER_NODE` | Реєструвати ноду | Orchestrator |
|
||||
| `MANAGE_MEMBERS` | Керувати учасниками MicroDAO | Orchestrator |
|
||||
| `CITYWIDE_ACCESS` | Діяти у всьому місті | DAARION108, civic |
|
||||
| `DISTRICT_ADMIN` | Адмініструвати District-платформу | District Orchestrator |
|
||||
|
||||
---
|
||||
|
||||
# 8. Безпека та перевірка дозволів
|
||||
|
||||
Єдиний принцип:
|
||||
|
||||
> **Суб’єкт діє в межах своєї приписки + своїх assignment.**
|
||||
|
||||
Тобто:
|
||||
|
||||
* агент може діяти у своїй MicroDAO;
|
||||
* агент може діяти в іншій MicroDAO лише через assignment;
|
||||
* реєструвати ноду може тільки оркестратор MicroDAO-власника;
|
||||
* District керує підлеглими, але не змінює їхню власність.
|
||||
|
||||
---
|
||||
|
||||
# 9. Підсумок
|
||||
|
||||
* Governance базується на канонічній онтології.
|
||||
* Визначено роли agent'ів та дозволи.
|
||||
* Assignment — офіційний механізм співпраці.
|
||||
* District — розширення MicroDAO, а не нова сутність.
|
||||
* Модель готова до подальшого розширення (повний ACL/RBAC) без ломки існуючої логіки.
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
# DAARION_Person_Agent_DAIS_CoreTeam_PATCH_v1.md
|
||||
|
||||
## Patch Update: Human Auth Layer → Agent DAIS Identity → Core-Team Model
|
||||
|
||||
**Status:** Architectural Correction (Non-Breaking Patch)
|
||||
**Version:** 1.0
|
||||
**Scope:** Clarifies Human vs Agent, DAIS scope, Core-Team Agents, DAARION108, Civic Layer
|
||||
|
||||
---
|
||||
|
||||
# 0. Мета патча
|
||||
|
||||
Уточнити ключові концепції онтології DAARION.city, які не були зафіксовані повністю у фундаментальних документах:
|
||||
|
||||
1. різницю між **Human** та **Agent**,
|
||||
2. що таке **DAIS** і кому він належить,
|
||||
3. як люди взаємодіють із агентами,
|
||||
4. хто такі **Core-Team Agents** та як вони працюють у MicroDAO,
|
||||
5. чим є **DAARION108**,
|
||||
6. хто представляє місто (civic layer — DAARWIZZ),
|
||||
7. як MicroDAO стає простором співпраці людей і агентів.
|
||||
|
||||
Патч не змінює основні документи — лише уточнює семантику.
|
||||
|
||||
---
|
||||
|
||||
# 1. Human vs Agent
|
||||
|
||||
## 1.1. Human/User
|
||||
|
||||
* має Human-auth (email, wallet, Telegram, OTP);
|
||||
* веде акаунт, налаштування доступу;
|
||||
* **не має DAIS**;
|
||||
* взаємодіє з містом через агентів, яких створює та контролює.
|
||||
|
||||
## 1.2. Agent
|
||||
|
||||
* цифровий представник людини, MicroDAO або організації;
|
||||
* має DAIS (DID + keys + wallet + Matrix);
|
||||
* працює у MicroDAO та на нодах;
|
||||
* є власником кімнат, сторінок, інтерфейсів.
|
||||
|
||||
## 1.3. Взаємозв’язок
|
||||
|
||||
```
|
||||
Human (user)
|
||||
↓ володіє/керує
|
||||
Agents (1..N)
|
||||
↓ кожен має
|
||||
DAIS Identity
|
||||
↓ кожен приписаний до
|
||||
MicroDAO
|
||||
↓ може працювати на
|
||||
Nodes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. DAIS належить агенту, а не людині
|
||||
|
||||
* DAIS містить DID, ключі, wallets, Matrix handle, signature domains.
|
||||
* DAIS = цифрове тіло агента.
|
||||
* Людина має Human Auth і управляє агентом, але не є DID.
|
||||
|
||||
---
|
||||
|
||||
# 3. Core-Team Agents
|
||||
|
||||
* новий клас агентів із розширеними повноваженнями;
|
||||
* ролі: CEO Agent, CTO Agent, CISO Agent, Architect, Product Lead, DevOps Lead, Legal Agent, HR Agent;
|
||||
* мають доступ до всієї MicroDAO, координують роботу команд;
|
||||
* у District — керують підлеглими підрозділами.
|
||||
|
||||
---
|
||||
|
||||
# 4. Core-Team у District
|
||||
|
||||
* District = MicroDAO-платформа;
|
||||
* має власний **Core-Team Console**;
|
||||
* може будувати міні-місто / екосистему;
|
||||
* core-team агентів District керують підлеглими MicroDAO.
|
||||
|
||||
---
|
||||
|
||||
# 5. DAARION108
|
||||
|
||||
* Core-Team MicroDAO «DAARION DAO»;
|
||||
* не civic layer, не міська підтримка;
|
||||
* це організаційна команда (аналог команди OpenAI, але AI-команда);
|
||||
* працює на Node2;
|
||||
* виконує ролі CEO/CTO/Architect/PM/etc.
|
||||
|
||||
---
|
||||
|
||||
# 6. Civic Layer (DAARWIZZ)
|
||||
|
||||
* окремий шар: міський інтерфейс для громадян;
|
||||
* агенти: DAARWIZZ (мер), навігатори, модератори, онбордери;
|
||||
* живуть у root MicroDAO DAARION;
|
||||
* мають `service_scope = city`.
|
||||
|
||||
---
|
||||
|
||||
# 7. MicroDAO як простір співпраці
|
||||
|
||||
* MicroDAO = workspace, де одночасно працюють люди та агенти;
|
||||
* містить проєкти, канбан, кімнати, core-team, ноди;
|
||||
* кожне MicroDAO може виставити публічні front-rooms у місті;
|
||||
* DAARION (root MicroDAO) теж має свій MicroDAO-інтерфейс.
|
||||
|
||||
---
|
||||
|
||||
# 8. Інваріанти, які додає патч
|
||||
|
||||
1. **Human ≠ Agent.** Людина управляє агентом, але не є DID.
|
||||
2. **DAIS належить агенту.** DID/ключі — це тіло агента.
|
||||
3. **Core-Team Agents** — офіційний клас із розширеними правами.
|
||||
4. **DAARION108** = core-team MicroDAO «DAARION DAO».
|
||||
5. **Civic Layer (DAARWIZZ)** — незалежний шар, який обслуговує місто.
|
||||
6. **MicroDAO** = простір співпраці людей і агентів.
|
||||
|
||||
---
|
||||
|
||||
# 9. Документи, які доповнює патч
|
||||
|
||||
* `DAARION_Ontology_Core_v1.md`
|
||||
* `User_Onboarding_And_Identity_Layer_v1.md`
|
||||
* `microdao_Governance_And_Permissions_v1.md`
|
||||
* `microdao_Data_Model_UPDATE_v1.md`
|
||||
* `DAARION_Identity_And_Access_Draft_v1.md`
|
||||
|
||||
---
|
||||
|
||||
# 10. Підсумок
|
||||
|
||||
Патч закріплює правильну концепцію:
|
||||
|
||||
* **DAIS = identity agent, not human.**
|
||||
* **Human → controls → Agents.**
|
||||
* **Agents → мають DAIS → діють у світі.**
|
||||
* **Core-Team Agents** — ключовий клас для MicroDAO/District.
|
||||
* **DAARION108** — core-team DAARION DAO.
|
||||
* **DAARWIZZ** + civic агенти — інтерфейс міста.
|
||||
|
||||
Документ завершено.
|
||||
|
||||
214
docs/tasks/TASK_FOUNDATION_IMPLEMENTATION.md
Normal file
214
docs/tasks/TASK_FOUNDATION_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# TASK: Foundation Implementation in MVP
|
||||
|
||||
**Status:** ✅ Implemented
|
||||
**Priority:** High
|
||||
**Completed:** 2025-11-29
|
||||
**Dependencies:** FOUNDATION_UPDATE документи (завершено)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Огляд
|
||||
|
||||
Впровадження оновлень архітектури FOUNDATION_UPDATE в MVP:
|
||||
- Оновлення Data Model (міграції)
|
||||
- Нові NATS events
|
||||
- Backend API оновлення
|
||||
- Frontend оновлення
|
||||
|
||||
---
|
||||
|
||||
## ✅ Що вже є (аналіз)
|
||||
|
||||
### Database
|
||||
- [x] `agents.is_orchestrator` (boolean) - частковий аналог `role`
|
||||
- [x] `microdaos.is_platform` (boolean) - частковий аналог `type=district`
|
||||
- [x] `microdaos.parent_microdao_id` - ієрархія
|
||||
- [x] `microdaos.orchestrator_agent_id` - primary orchestrator
|
||||
- [x] `nodes.modules`, `nodes.gpu`, `nodes.roles` - capabilities
|
||||
- [x] `microdao_agents` - зв'язок агентів з мікроДАО
|
||||
|
||||
### Backend
|
||||
- [x] DAO Factory service
|
||||
- [x] Registry service
|
||||
- [x] Wallet service
|
||||
- [x] PDP (Policy Decision Point)
|
||||
|
||||
### Frontend
|
||||
- [x] Agent Hub UI
|
||||
- [x] MicroDAO Console
|
||||
- [x] Node Cabinets
|
||||
- [x] City Page (базова)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Що потрібно реалізувати
|
||||
|
||||
### Phase 1: Database Schema Update (Міграція 027) ✅
|
||||
|
||||
```sql
|
||||
-- 027_foundation_ontology_update.sql
|
||||
```
|
||||
|
||||
1. **Agents table** ✅
|
||||
- [x] `dais_identity_id text` - DAIS прив'язка
|
||||
- [x] `agent_role` enum - замість is_orchestrator
|
||||
- [x] `agent_service_scope` enum
|
||||
- [x] `home_microdao_id text` - базова приписка
|
||||
- [x] `home_node_id text` - базова нода
|
||||
|
||||
2. **MicroDAOs table** ✅
|
||||
- [x] `dao_type` enum (root/standard/district)
|
||||
- [x] `primary_orchestrator_agent_id text`
|
||||
- [x] `wallet_address text`
|
||||
|
||||
3. **Nodes table** ✅
|
||||
- [x] `kind` enum (smartphone/laptop/edge/datacenter/iot/gpu-cluster)
|
||||
- [x] `capabilities jsonb`
|
||||
- [x] `node_status` enum (provisioning/active/draining/retired)
|
||||
|
||||
4. **Нова таблиця: agent_assignments** ✅
|
||||
- [x] All fields implemented
|
||||
|
||||
5. **DAIS tables (нові)** ✅
|
||||
- [x] `dais_identities`
|
||||
- [x] `dais_emails`
|
||||
- [x] `dais_wallets`
|
||||
- [x] `dais_keys`
|
||||
|
||||
6. **Rooms table (нова)** ✅
|
||||
- [x] Full Rooms Layer support
|
||||
|
||||
7. **Event outbox (нова)** ✅
|
||||
- [x] For NATS event delivery
|
||||
|
||||
### Phase 2: NATS Events (Event Catalog) ✅
|
||||
|
||||
- [x] `dagion.agent.promoted_to_orchestrator`
|
||||
- [x] `dagion.microdao.created`
|
||||
- [x] `dagion.node.registered`
|
||||
- [x] `dagion.microdao.promoted_to_district`
|
||||
- [x] `dagion.agent.assignment_created`
|
||||
- [x] `dagion.agent.assignment_ended`
|
||||
|
||||
### Phase 3: Backend API Updates ✅
|
||||
|
||||
1. **DAIS routes** ✅
|
||||
- [x] `POST /api/v1/dais/identity`
|
||||
- [x] `GET /api/v1/dais/:id`
|
||||
- [x] `GET /api/v1/dais/agent/:agentId`
|
||||
- [x] `POST /api/v1/dais/:id/email`
|
||||
- [x] `POST /api/v1/dais/:id/email/verify`
|
||||
- [x] `POST /api/v1/dais/:id/wallet`
|
||||
- [x] `POST /api/v1/dais/:id/wallet/verify`
|
||||
- [x] `POST /api/v1/dais/:id/promote-to-orchestrator`
|
||||
|
||||
2. **Assignment routes** ✅
|
||||
- [x] `POST /api/v1/assignments`
|
||||
- [x] `DELETE /api/v1/assignments/:id`
|
||||
- [x] `GET /api/v1/assignments/agent/:agentId`
|
||||
- [x] `GET /api/v1/assignments/microdao/:microdaoId`
|
||||
- [x] `GET /api/v1/assignments/citywide`
|
||||
- [x] `GET /api/v1/assignments/agent/:agentId/scope`
|
||||
- [x] `GET /api/v1/assignments/check`
|
||||
|
||||
### Phase 4: Frontend Updates ✅
|
||||
|
||||
1. **Types** ✅
|
||||
- [x] `src/types/ontology.ts` - all ontology types
|
||||
|
||||
2. **API Clients** ✅
|
||||
- [x] `src/api/dais.ts`
|
||||
- [x] `src/api/assignments.ts`
|
||||
|
||||
3. **Components** ✅
|
||||
- [x] `DaisProfileCard.tsx`
|
||||
- [x] `AssignmentsPanel.tsx`
|
||||
- [x] `OntologyBadge.tsx` (MicrodaoType, NodeStatus, NodeKind, AgentRole, ServiceScope)
|
||||
|
||||
---
|
||||
|
||||
## 📁 Файли для створення/оновлення
|
||||
|
||||
### Backend
|
||||
```
|
||||
backend/
|
||||
├── domain/
|
||||
│ ├── dais/
|
||||
│ │ └── types.ts # DAIS types
|
||||
│ ├── agent/
|
||||
│ │ └── types.ts # оновити
|
||||
│ └── assignment/
|
||||
│ └── types.ts # нові типи
|
||||
├── http/
|
||||
│ ├── dais.routes.ts # новий
|
||||
│ └── assignment.routes.ts # новий
|
||||
├── services/
|
||||
│ ├── dais/
|
||||
│ │ └── dais.service.ts # новий
|
||||
│ └── assignment/
|
||||
│ └── assignment.service.ts # новий
|
||||
└── infra/
|
||||
└── nats/
|
||||
└── events.ts # оновити events catalog
|
||||
```
|
||||
|
||||
### Frontend
|
||||
```
|
||||
src/
|
||||
├── api/
|
||||
│ ├── dais.ts # новий
|
||||
│ └── assignments.ts # новий
|
||||
├── features/
|
||||
│ ├── dais/
|
||||
│ │ └── components/ # DAIS UI
|
||||
│ └── assignments/
|
||||
│ └── AssignmentsPanel.tsx
|
||||
└── types/
|
||||
├── dais.ts # DAIS types
|
||||
└── ontology.ts # Agent/MicroDAO/Node types
|
||||
```
|
||||
|
||||
### Migrations
|
||||
```
|
||||
migrations/
|
||||
└── 027_foundation_ontology_update.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Acceptance Criteria
|
||||
|
||||
1. **Database**
|
||||
- [ ] Міграція 027 виконана успішно
|
||||
- [ ] Всі таблиці відповідають Data Model v1
|
||||
|
||||
2. **Backend**
|
||||
- [ ] API routes працюють
|
||||
- [ ] NATS events публікуються
|
||||
|
||||
3. **Frontend**
|
||||
- [ ] Agent Console показує DAIS/assignments
|
||||
- [ ] MicroDAO показує type/hierarchy
|
||||
- [ ] Nodes показують lifecycle
|
||||
|
||||
4. **Non-Breaking**
|
||||
- [ ] Існуючий функціонал працює
|
||||
- [ ] Backward compatibility збережено
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Порядок виконання
|
||||
|
||||
1. **Створити міграцію** 027_foundation_ontology_update.sql
|
||||
2. **Застосувати міграцію** на dev БД
|
||||
3. **Оновити backend types** для нових полів
|
||||
4. **Додати API routes** для DAIS, assignments
|
||||
5. **Оновити frontend types**
|
||||
6. **Додати UI компоненти** для нового функціоналу
|
||||
7. **Тестування** локально
|
||||
8. **Deploy** на production
|
||||
|
||||
---
|
||||
|
||||
**Готовий до виконання?** Починаємо з Phase 1: Database Migration.
|
||||
|
||||
112
docs/tasks/TASK_PHASE_FOUNDATION_UPDATE.md
Normal file
112
docs/tasks/TASK_PHASE_FOUNDATION_UPDATE.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# TASK_PHASE_FOUNDATION_UPDATE.md
|
||||
|
||||
## DAARION.city — Fundamental Architecture Update (Non-Breaking)
|
||||
|
||||
**Ціль:** зафіксувати онтологію системи (Agent → MicroDAO → Node → District), стандартизувати онбординг, DAIS-ідентичність, типи агентів, події та базовий Data Model — **без порушення існуючого коду / документації**.
|
||||
|
||||
---
|
||||
|
||||
# 0. Принципи фази
|
||||
|
||||
1. **Нічого не ламаємо**, лише додаємо надбудову поверх існуючих документів.
|
||||
2. Усе, що створюється в цій фазі — фундаментальна архітектура DAARION.
|
||||
3. Cursor і DAGI-агенти повинні мати єдине джерело істини щодо реєстрації, агентів, мікроДАО, нод, ролей, подій.
|
||||
|
||||
---
|
||||
|
||||
# 1. Вихідні файли після завершення фази
|
||||
|
||||
Фаза повинна створити або оновити **13+ документів**.
|
||||
|
||||
## Головні
|
||||
|
||||
1. `DAARION_Ontology_Core_v1.md`
|
||||
2. `User_Onboarding_And_Identity_Layer_v1.md`
|
||||
3. `Technical_Description_microdao_PATCH_Ontology.md`
|
||||
4. `microdao_Data_Model_UPDATE_v1.md`
|
||||
5. `microdao_Event_Catalog_EXTENDED_v1.md`
|
||||
6. `microdao_Governance_And_Permissions_v1.md`
|
||||
7. `DAARION_Identity_And_Access_Draft_v1.md`
|
||||
8. `Rooms_Layer_Architecture_v1.md`
|
||||
9. `MicroDAO_Interface_Architecture_v1.md`
|
||||
10. `City_Interface_Architecture_v1.md`
|
||||
11. `Agents_Interface_Architecture_v1.md`
|
||||
12. `Nodes_Interface_Architecture_v1.md`
|
||||
|
||||
## Допоміжні
|
||||
|
||||
* `helpers/ontology-summary.md`
|
||||
* `helpers/onboarding-flow-diagram.mermaid`
|
||||
* `helpers/agent-types-matrix.md`
|
||||
* `helpers/microdao-lifecycle.md`
|
||||
* `helpers/node-lifecycle.md`
|
||||
* `helpers/event-schemas.json`
|
||||
|
||||
## Патчі
|
||||
|
||||
* `patches/DAARION_Person_Agent_DAIS_CoreTeam_PATCH_v1.md`
|
||||
|
||||
---
|
||||
|
||||
# 2. Tasks
|
||||
|
||||
1. **TASK 1 — Ontology Core** → створити базову онтологію (файл №1).
|
||||
2. **TASK 2 — Onboarding & Identity** → email/wallet/SIWE/DAIS (файл №2).
|
||||
3. **TASK 3 — Patch Technical Description** → секції онтології в існуючому описі microdao.
|
||||
4. **TASK 4 — Data Model Update** → agents/microdaos/nodes/assignments.
|
||||
5. **TASK 5 — Event Catalog** → додати 6 нових подій та схеми.
|
||||
6. **TASK 6 — Governance Layer** → ролі, ACL, district, assignments.
|
||||
7. **TASK 7 — Identity & Access Draft** → DAIS як IAM.
|
||||
8. **TASK 8 — Rooms Layer** → city/microdao/district rooms.
|
||||
9. **TASK 9 — MicroDAO Interface** → повний UI шару.
|
||||
10. **TASK 10 — City Interface** → City Square, public rooms, portals.
|
||||
11. **TASK 11 — Agents Interface** → agent-centric UI.
|
||||
12. **TASK 12 — Nodes Interface** → node dashboards/control rooms.
|
||||
13. **TASK 13 — Helper Files** → TL;DR, mermaid, lifecycles, event schemas.
|
||||
|
||||
---
|
||||
|
||||
# 3. Порядок виконання
|
||||
|
||||
1. Ontology → Onboarding → Patch → Data Model → Event Catalog → Governance → Identity & Access.
|
||||
2. Після цього Rooms Layer та UI документи (MicroDAO/City/Agents/Nodes).
|
||||
3. Завершити helper-файлами та README.
|
||||
|
||||
---
|
||||
|
||||
# 4. Гарантії «Non-Breaking Update»
|
||||
|
||||
* Неторкнені частини коду/документації залишаються валідними.
|
||||
* Усі інваріанти вводяться як надбудова.
|
||||
* Уся логіка створення MicroDAO/агента/нод залишається робочою.
|
||||
|
||||
---
|
||||
|
||||
# Acceptance checklist
|
||||
|
||||
1. **Документи**
|
||||
* [x] Створено/оновлено всі файли, перелічені вище. ✅ (20 файлів)
|
||||
* [x] README у `docs/foundation/` описує структуру. ✅
|
||||
2. **Посилання**
|
||||
* [x] Перехресні посилання між онтологією, моделлю даних, подіями, інтерфейсами. ✅
|
||||
3. **Helper-файли**
|
||||
* [x] TL;DR, діаграма онбордингу, матриця агентів, lifecycles, event schemas. ✅ (6 файлів)
|
||||
4. **Патчі**
|
||||
* [x] Застосовано патч Human vs Agent vs DAIS vs Core-Team. ✅
|
||||
5. **Task readiness**
|
||||
* [x] `TASK_PHASE_FOUNDATION_UPDATE.md` описує всі deliverables. ✅
|
||||
* [x] Можна давати Cursor-таски для реалізації MVP на основі цих документів. ✅
|
||||
|
||||
---
|
||||
|
||||
## ✅ PHASE COMPLETE
|
||||
|
||||
**Дата завершення:** 2024-11-29
|
||||
|
||||
**Статистика:**
|
||||
- Основних документів: 12
|
||||
- Helper-файлів: 6
|
||||
- Патчів: 1
|
||||
- README: 1
|
||||
- **Всього: 20 файлів**
|
||||
|
||||
373
migrations/027_foundation_ontology_update.sql
Normal file
373
migrations/027_foundation_ontology_update.sql
Normal file
@@ -0,0 +1,373 @@
|
||||
-- Migration 027: Foundation Ontology Update
|
||||
-- Purpose: Implement DAARION.city ontology (Agent → MicroDAO → Node → District)
|
||||
-- Based on: docs/foundation/microdao_Data_Model_UPDATE_v1.md
|
||||
-- Date: 2025-11-29
|
||||
-- Status: Non-Breaking Update
|
||||
|
||||
-- ============================================================================
|
||||
-- 0. ENUM TYPES
|
||||
-- ============================================================================
|
||||
|
||||
-- Agent role enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'agent_role') THEN
|
||||
CREATE TYPE agent_role AS ENUM ('regular', 'orchestrator');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Agent service scope enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'service_scope') THEN
|
||||
CREATE TYPE service_scope AS ENUM ('microdao', 'district', 'city');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- MicroDAO type enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'microdao_type') THEN
|
||||
CREATE TYPE microdao_type AS ENUM ('root', 'standard', 'district');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Node kind enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'node_kind') THEN
|
||||
CREATE TYPE node_kind AS ENUM ('smartphone', 'laptop', 'edge', 'datacenter', 'iot', 'gpu-cluster');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Node status enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'node_status') THEN
|
||||
CREATE TYPE node_status AS ENUM ('provisioning', 'active', 'draining', 'retired');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Assignment scope enum (same as service_scope but for assignments)
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'assignment_scope') THEN
|
||||
CREATE TYPE assignment_scope AS ENUM ('microdao', 'district', 'city');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- DAIS trust level enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'dais_trust_level') THEN
|
||||
CREATE TYPE dais_trust_level AS ENUM ('guest', 'agent', 'verified', 'orchestrator', 'operator');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ============================================================================
|
||||
-- 1. DAIS IDENTITY TABLES (DAIS = DAARION Autonomous Identity System)
|
||||
-- ============================================================================
|
||||
|
||||
-- Main DAIS identity table
|
||||
CREATE TABLE IF NOT EXISTS dais_identities (
|
||||
id TEXT PRIMARY KEY,
|
||||
did TEXT NOT NULL UNIQUE, -- format: did:daarion:<uuid>
|
||||
default_email TEXT,
|
||||
default_wallet TEXT,
|
||||
matrix_handle TEXT, -- format: @<agent_id>:matrix.daarion.city
|
||||
trust_level dais_trust_level NOT NULL DEFAULT 'agent',
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_identities_did ON dais_identities(did);
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_identities_trust ON dais_identities(trust_level);
|
||||
|
||||
-- DAIS email identities
|
||||
CREATE TABLE IF NOT EXISTS dais_emails (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
dais_id TEXT NOT NULL REFERENCES dais_identities(id) ON DELETE CASCADE,
|
||||
email TEXT NOT NULL,
|
||||
verified BOOLEAN NOT NULL DEFAULT false,
|
||||
verified_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE(dais_id, email)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_emails_dais ON dais_emails(dais_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_emails_email ON dais_emails(email);
|
||||
|
||||
-- DAIS wallet identities
|
||||
CREATE TABLE IF NOT EXISTS dais_wallets (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
dais_id TEXT NOT NULL REFERENCES dais_identities(id) ON DELETE CASCADE,
|
||||
wallet_address TEXT NOT NULL,
|
||||
network TEXT NOT NULL DEFAULT 'evm', -- evm, ton, solana
|
||||
verified BOOLEAN NOT NULL DEFAULT false,
|
||||
verified_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE(dais_id, wallet_address)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_wallets_dais ON dais_wallets(dais_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_wallets_address ON dais_wallets(wallet_address);
|
||||
|
||||
-- DAIS public keys
|
||||
CREATE TABLE IF NOT EXISTS dais_keys (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
dais_id TEXT NOT NULL REFERENCES dais_identities(id) ON DELETE CASCADE,
|
||||
key_type TEXT NOT NULL, -- ed25519, x25519, secp256k1
|
||||
public_key TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
revoked_at TIMESTAMPTZ,
|
||||
UNIQUE(dais_id, key_type, public_key)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_dais_keys_dais ON dais_keys(dais_id);
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. AGENTS TABLE UPDATE
|
||||
-- ============================================================================
|
||||
|
||||
-- Add new ontology fields to agents
|
||||
ALTER TABLE agents ADD COLUMN IF NOT EXISTS dais_identity_id TEXT REFERENCES dais_identities(id);
|
||||
ALTER TABLE agents ADD COLUMN IF NOT EXISTS agent_role agent_role DEFAULT 'regular';
|
||||
ALTER TABLE agents ADD COLUMN IF NOT EXISTS agent_service_scope service_scope;
|
||||
ALTER TABLE agents ADD COLUMN IF NOT EXISTS home_microdao_id TEXT;
|
||||
ALTER TABLE agents ADD COLUMN IF NOT EXISTS home_node_id TEXT;
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_agents_dais ON agents(dais_identity_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_agents_role ON agents(agent_role);
|
||||
CREATE INDEX IF NOT EXISTS idx_agents_service_scope ON agents(agent_service_scope);
|
||||
CREATE INDEX IF NOT EXISTS idx_agents_home_microdao ON agents(home_microdao_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_agents_home_node ON agents(home_node_id);
|
||||
|
||||
-- Migrate existing is_orchestrator to agent_role
|
||||
UPDATE agents
|
||||
SET agent_role = 'orchestrator'::agent_role
|
||||
WHERE is_orchestrator = true AND agent_role IS NULL;
|
||||
|
||||
UPDATE agents
|
||||
SET agent_role = 'regular'::agent_role
|
||||
WHERE is_orchestrator = false AND agent_role IS NULL;
|
||||
|
||||
-- Set default home_microdao_id for existing agents
|
||||
UPDATE agents
|
||||
SET home_microdao_id = primary_microdao_id
|
||||
WHERE home_microdao_id IS NULL AND primary_microdao_id IS NOT NULL;
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. MICRODAOS TABLE UPDATE
|
||||
-- ============================================================================
|
||||
|
||||
-- Add new ontology fields to microdaos
|
||||
ALTER TABLE microdaos ADD COLUMN IF NOT EXISTS dao_type microdao_type DEFAULT 'standard';
|
||||
ALTER TABLE microdaos ADD COLUMN IF NOT EXISTS primary_orchestrator_agent_id TEXT;
|
||||
ALTER TABLE microdaos ADD COLUMN IF NOT EXISTS wallet_address TEXT;
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_microdaos_type ON microdaos(dao_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_microdaos_primary_orchestrator ON microdaos(primary_orchestrator_agent_id);
|
||||
|
||||
-- Migrate existing is_platform to dao_type
|
||||
UPDATE microdaos
|
||||
SET dao_type = 'district'::microdao_type
|
||||
WHERE is_platform = true AND dao_type IS NULL;
|
||||
|
||||
UPDATE microdaos
|
||||
SET dao_type = 'standard'::microdao_type
|
||||
WHERE is_platform = false AND dao_type IS NULL;
|
||||
|
||||
-- Set DAARION as root
|
||||
UPDATE microdaos
|
||||
SET dao_type = 'root'::microdao_type
|
||||
WHERE slug = 'daarion';
|
||||
|
||||
-- Copy orchestrator_agent_id to primary_orchestrator_agent_id
|
||||
UPDATE microdaos
|
||||
SET primary_orchestrator_agent_id = orchestrator_agent_id
|
||||
WHERE primary_orchestrator_agent_id IS NULL AND orchestrator_agent_id IS NOT NULL;
|
||||
|
||||
-- ============================================================================
|
||||
-- 4. NODES TABLE UPDATE
|
||||
-- ============================================================================
|
||||
|
||||
-- Add new ontology fields to nodes
|
||||
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS kind node_kind DEFAULT 'datacenter';
|
||||
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS node_status node_status DEFAULT 'active';
|
||||
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS capabilities JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS microdao_id TEXT;
|
||||
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS last_heartbeat TIMESTAMPTZ;
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_nodes_kind ON nodes(kind);
|
||||
CREATE INDEX IF NOT EXISTS idx_nodes_status ON nodes(node_status);
|
||||
CREATE INDEX IF NOT EXISTS idx_nodes_microdao ON nodes(microdao_id);
|
||||
|
||||
-- Migrate existing nodes
|
||||
UPDATE nodes
|
||||
SET kind = 'datacenter'::node_kind,
|
||||
node_status = 'active'::node_status
|
||||
WHERE kind IS NULL;
|
||||
|
||||
-- Build capabilities from existing gpu/modules columns
|
||||
UPDATE nodes
|
||||
SET capabilities = jsonb_build_object(
|
||||
'gpu', COALESCE(gpu, '{}'::jsonb),
|
||||
'modules', COALESCE(modules, '[]'::jsonb),
|
||||
'roles', COALESCE(array_to_json(roles), '[]'::json)
|
||||
)
|
||||
WHERE capabilities = '{}'::jsonb;
|
||||
|
||||
-- Set DAARION as owner for existing nodes
|
||||
UPDATE nodes
|
||||
SET microdao_id = (SELECT id FROM microdaos WHERE slug = 'daarion' LIMIT 1)
|
||||
WHERE microdao_id IS NULL;
|
||||
|
||||
-- ============================================================================
|
||||
-- 5. AGENT ASSIGNMENTS TABLE (NEW)
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_assignments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
||||
target_microdao_id TEXT NOT NULL,
|
||||
scope assignment_scope NOT NULL DEFAULT 'microdao',
|
||||
role TEXT NOT NULL, -- advisor, security, mentor, ops, core-team
|
||||
start_ts TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
end_ts TIMESTAMPTZ,
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE(agent_id, target_microdao_id, role)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_assignments_agent ON agent_assignments(agent_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_assignments_target ON agent_assignments(target_microdao_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_assignments_scope ON agent_assignments(scope);
|
||||
CREATE INDEX IF NOT EXISTS idx_assignments_active ON agent_assignments(agent_id) WHERE end_ts IS NULL;
|
||||
|
||||
-- Migrate existing microdao_agents to assignments
|
||||
INSERT INTO agent_assignments (agent_id, target_microdao_id, scope, role)
|
||||
SELECT
|
||||
agent_id,
|
||||
microdao_id,
|
||||
'microdao'::assignment_scope,
|
||||
COALESCE(role, 'member')
|
||||
FROM microdao_agents
|
||||
ON CONFLICT (agent_id, target_microdao_id, role) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- 6. ROOMS TABLE (City/MicroDAO/District rooms)
|
||||
-- ============================================================================
|
||||
|
||||
-- Room type enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'room_type') THEN
|
||||
CREATE TYPE room_type AS ENUM ('city-room', 'dao-room', 'front-room', 'agent-room', 'event-room', 'district-room');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Room visibility enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'room_visibility') THEN
|
||||
CREATE TYPE room_visibility AS ENUM ('private', 'members', 'public-city', 'public-global');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Space scope enum
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'space_scope') THEN
|
||||
CREATE TYPE space_scope AS ENUM ('city', 'microdao', 'district');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Rooms table (foundation for Rooms Layer)
|
||||
CREATE TABLE IF NOT EXISTS rooms (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_type TEXT NOT NULL, -- city, microdao, district, agent
|
||||
owner_id TEXT NOT NULL,
|
||||
type room_type NOT NULL DEFAULT 'dao-room',
|
||||
space_scope space_scope NOT NULL DEFAULT 'microdao',
|
||||
visibility room_visibility NOT NULL DEFAULT 'members',
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
matrix_room_id TEXT,
|
||||
is_portal BOOLEAN NOT NULL DEFAULT false,
|
||||
portal_target_microdao_id TEXT,
|
||||
map_x INTEGER,
|
||||
map_y INTEGER,
|
||||
zone TEXT,
|
||||
mesh_id TEXT, -- for 3D
|
||||
primary_agent_id TEXT,
|
||||
team_agent_ids TEXT[],
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rooms_owner ON rooms(owner_type, owner_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_rooms_type ON rooms(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_rooms_scope ON rooms(space_scope);
|
||||
CREATE INDEX IF NOT EXISTS idx_rooms_visibility ON rooms(visibility);
|
||||
CREATE INDEX IF NOT EXISTS idx_rooms_portal ON rooms(is_portal) WHERE is_portal = true;
|
||||
|
||||
-- ============================================================================
|
||||
-- 7. EVENT OUTBOX (for NATS events)
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS event_outbox (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
event_type TEXT NOT NULL, -- dagion.agent.promoted_to_orchestrator, etc.
|
||||
subject TEXT NOT NULL, -- NATS subject
|
||||
payload JSONB NOT NULL,
|
||||
version TEXT NOT NULL DEFAULT '1.0',
|
||||
status TEXT NOT NULL DEFAULT 'pending', -- pending, published, failed
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
published_at TIMESTAMPTZ,
|
||||
error_message TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_outbox_status ON event_outbox(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_outbox_type ON event_outbox(event_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_outbox_pending ON event_outbox(created_at) WHERE status = 'pending';
|
||||
|
||||
-- ============================================================================
|
||||
-- 8. COMMENTS
|
||||
-- ============================================================================
|
||||
|
||||
COMMENT ON TABLE dais_identities IS 'DAIS (DAARION Autonomous Identity System) - unified digital identity';
|
||||
COMMENT ON TABLE dais_emails IS 'Email identities linked to DAIS';
|
||||
COMMENT ON TABLE dais_wallets IS 'Wallet identities (EVM/TON) linked to DAIS';
|
||||
COMMENT ON TABLE dais_keys IS 'Public keys for signing/encryption (Ed25519, X25519, secp256k1)';
|
||||
COMMENT ON TABLE agent_assignments IS 'Agent work assignments to other MicroDAO/District/City';
|
||||
COMMENT ON TABLE rooms IS 'Rooms Layer - city/microdao/district rooms and portals';
|
||||
COMMENT ON TABLE event_outbox IS 'Outbox pattern for transactional NATS event delivery';
|
||||
|
||||
COMMENT ON COLUMN agents.agent_role IS 'Agent role: regular or orchestrator';
|
||||
COMMENT ON COLUMN agents.agent_service_scope IS 'Service scope: microdao, district, or city';
|
||||
COMMENT ON COLUMN agents.home_microdao_id IS 'Primary MicroDAO affiliation (ontology invariant)';
|
||||
COMMENT ON COLUMN agents.home_node_id IS 'Primary node for agent execution';
|
||||
|
||||
COMMENT ON COLUMN microdaos.dao_type IS 'MicroDAO type: root (DAARION), standard, or district';
|
||||
COMMENT ON COLUMN microdaos.primary_orchestrator_agent_id IS 'Main orchestrator agent for this MicroDAO';
|
||||
|
||||
COMMENT ON COLUMN nodes.kind IS 'Node hardware type: smartphone, laptop, edge, datacenter, iot, gpu-cluster';
|
||||
COMMENT ON COLUMN nodes.node_status IS 'Lifecycle status: provisioning, active, draining, retired';
|
||||
COMMENT ON COLUMN nodes.capabilities IS 'Node capabilities: CPU, GPU, RAM, network, sensors';
|
||||
|
||||
-- ============================================================================
|
||||
-- 9. SEED DATA - City Rooms
|
||||
-- ============================================================================
|
||||
|
||||
-- Create default city rooms
|
||||
INSERT INTO rooms (id, owner_type, owner_id, type, space_scope, visibility, name, description, primary_agent_id)
|
||||
VALUES
|
||||
('city-lobby', 'city', 'daarion', 'city-room', 'city', 'public-city', 'City Lobby', 'Main entrance to DAARION.city', 'dario'),
|
||||
('city-square', 'city', 'daarion', 'city-room', 'city', 'public-city', 'City Square', 'Central public space', 'dario'),
|
||||
('city-news', 'city', 'daarion', 'city-room', 'city', 'public-city', 'City News', 'Latest news and announcements', 'daria'),
|
||||
('city-help', 'city', 'daarion', 'city-room', 'city', 'public-city', 'City Help', 'Support and assistance', 'daria'),
|
||||
('city-events', 'city', 'daarion', 'city-room', 'city', 'public-city', 'City Events', 'Events and activities', 'daarwizz')
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- DONE
|
||||
-- ============================================================================
|
||||
|
||||
SELECT 'Migration 027 completed: Foundation Ontology Update' as result;
|
||||
|
||||
@@ -80,7 +80,7 @@ async def handle_parser_document_parsed(msg):
|
||||
}
|
||||
|
||||
# Ingest the document
|
||||
result = ingest_parsed_document(
|
||||
result = await ingest_parsed_document(
|
||||
dao_id=dao_id or team_id,
|
||||
doc_id=doc_id,
|
||||
parsed_json=mock_parsed_json,
|
||||
|
||||
@@ -18,7 +18,7 @@ from app.events import publish_document_ingested, publish_document_indexed
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ingest_parsed_document(
|
||||
async def ingest_parsed_document(
|
||||
dao_id: str,
|
||||
doc_id: str,
|
||||
parsed_json: Dict[str, Any],
|
||||
@@ -81,46 +81,14 @@ def ingest_parsed_document(
|
||||
)
|
||||
|
||||
# Publish events
|
||||
try:
|
||||
# First publish rag.document.ingested event
|
||||
await publish_document_ingested(
|
||||
doc_id=doc_id,
|
||||
team_id=dao_id,
|
||||
dao_id=dao_id,
|
||||
chunk_count=written_docs,
|
||||
indexed=True,
|
||||
visibility="public",
|
||||
metadata={
|
||||
"ingestion_time_ms": round(pipeline_time * 1000),
|
||||
"embed_model": settings.EMBEDDING_MODEL or "bge-m3@v1",
|
||||
"pages_processed": pages_count,
|
||||
"blocks_processed": blocks_count
|
||||
}
|
||||
)
|
||||
logger.info(f"Published rag.document.ingested event for doc_id={doc_id}")
|
||||
|
||||
# Then publish rag.document.indexed event
|
||||
chunk_ids = []
|
||||
for i in range(written_docs):
|
||||
chunk_ids.append(f"{doc_id}_chunk_{i+1}")
|
||||
|
||||
await publish_document_indexed(
|
||||
doc_id=doc_id,
|
||||
team_id=dao_id,
|
||||
dao_id=dao_id,
|
||||
chunk_ids=chunk_ids,
|
||||
indexed=True,
|
||||
visibility="public",
|
||||
metadata={
|
||||
"indexing_time_ms": 0, # TODO: track actual indexing time
|
||||
"milvus_collection": "documents_v1",
|
||||
"neo4j_nodes_created": len(chunk_ids),
|
||||
"embed_model": settings.EMBEDDING_MODEL or "bge-m3@v1"
|
||||
}
|
||||
)
|
||||
logger.info(f"Published rag.document.indexed event for doc_id={doc_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to publish RAG events for doc_id={doc_id}: {e}")
|
||||
await _publish_events_async(
|
||||
dao_id=dao_id,
|
||||
doc_id=doc_id,
|
||||
written_docs=written_docs,
|
||||
pages_count=pages_count,
|
||||
blocks_count=blocks_count,
|
||||
pipeline_time=pipeline_time
|
||||
)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
@@ -229,6 +197,51 @@ def _parsed_json_to_documents(
|
||||
return documents
|
||||
|
||||
|
||||
async def _publish_events_async(
|
||||
dao_id: str,
|
||||
doc_id: str,
|
||||
written_docs: int,
|
||||
pages_count: int,
|
||||
blocks_count: int,
|
||||
pipeline_time: float
|
||||
):
|
||||
try:
|
||||
await publish_document_ingested(
|
||||
doc_id=doc_id,
|
||||
team_id=dao_id,
|
||||
dao_id=dao_id,
|
||||
chunk_count=written_docs,
|
||||
indexed=True,
|
||||
visibility="public",
|
||||
metadata={
|
||||
"ingestion_time_ms": round(pipeline_time * 1000),
|
||||
"embed_model": settings.EMBEDDING_MODEL or "bge-m3@v1",
|
||||
"pages_processed": pages_count,
|
||||
"blocks_processed": blocks_count
|
||||
}
|
||||
)
|
||||
logger.info(f"Published rag.document.ingested event for doc_id={doc_id}")
|
||||
|
||||
chunk_ids = [f"{doc_id}_chunk_{i+1}" for i in range(written_docs)]
|
||||
await publish_document_indexed(
|
||||
doc_id=doc_id,
|
||||
team_id=dao_id,
|
||||
dao_id=dao_id,
|
||||
chunk_ids=chunk_ids,
|
||||
indexed=True,
|
||||
visibility="public",
|
||||
metadata={
|
||||
"indexing_time_ms": 0,
|
||||
"milvus_collection": "documents_v1",
|
||||
"neo4j_nodes_created": len(chunk_ids),
|
||||
"embed_model": settings.EMBEDDING_MODEL or "bge-m3@v1"
|
||||
}
|
||||
)
|
||||
logger.info(f"Published rag.document.indexed event for doc_id={doc_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to publish RAG events for doc_id={doc_id}: {e}")
|
||||
|
||||
|
||||
def _create_ingest_pipeline() -> Pipeline:
|
||||
"""
|
||||
Create Haystack ingest pipeline
|
||||
|
||||
@@ -87,7 +87,7 @@ async def ingest_endpoint(request: IngestRequest):
|
||||
- user_id: Optional user identifier
|
||||
"""
|
||||
try:
|
||||
result = ingest_parsed_document(
|
||||
result = await ingest_parsed_document(
|
||||
dao_id=request.dao_id,
|
||||
doc_id=request.doc_id,
|
||||
parsed_json=request.parsed_json,
|
||||
|
||||
@@ -2,7 +2,7 @@ fastapi>=0.115.0
|
||||
uvicorn[standard]>=0.30.0
|
||||
pydantic>=2.0.0
|
||||
pydantic-settings>=2.0.0
|
||||
haystack-ai>=2.0.0
|
||||
farm-haystack[postgresql]>=1.25.3
|
||||
sentence-transformers>=2.2.0
|
||||
psycopg2-binary>=2.9.0
|
||||
httpx>=0.27.0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Встановити wget для healthcheck
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends wget \
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends wget curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
@@ -25,7 +25,7 @@ EXPOSE 8898
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD wget -qO- http://localhost:8898/health || exit 1
|
||||
CMD curl -f http://localhost:8898/health || exit 1
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8898"]
|
||||
|
||||
|
||||
110
src/api/assignments.ts
Normal file
110
src/api/assignments.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Agent Assignments API Client
|
||||
* Based on: docs/foundation/microdao_Governance_And_Permissions_v1.md
|
||||
*/
|
||||
|
||||
import { apiClient } from './client';
|
||||
import type {
|
||||
AgentAssignment,
|
||||
AgentScope,
|
||||
AssignmentScope,
|
||||
AssignmentRole
|
||||
} from '../types/ontology';
|
||||
|
||||
const BASE_URL = '/api/v1/assignments';
|
||||
|
||||
export interface CreateAssignmentRequest {
|
||||
agentId: string;
|
||||
targetMicrodaoId: string;
|
||||
scope: AssignmentScope;
|
||||
role: AssignmentRole | string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new agent assignment
|
||||
*/
|
||||
export async function createAssignment(
|
||||
request: CreateAssignmentRequest
|
||||
): Promise<AgentAssignment> {
|
||||
const response = await apiClient.post<{ data: AgentAssignment }>(
|
||||
BASE_URL,
|
||||
request
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* End an agent assignment
|
||||
*/
|
||||
export async function endAssignment(assignmentId: string): Promise<void> {
|
||||
await apiClient.delete(`${BASE_URL}/${assignmentId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active assignments for an agent
|
||||
*/
|
||||
export async function getAgentAssignments(
|
||||
agentId: string
|
||||
): Promise<AgentAssignment[]> {
|
||||
const response = await apiClient.get<{ data: AgentAssignment[] }>(
|
||||
`${BASE_URL}/agent/${agentId}`
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all assignments for a MicroDAO
|
||||
*/
|
||||
export async function getMicrodaoAssignments(
|
||||
microdaoId: string
|
||||
): Promise<AgentAssignment[]> {
|
||||
const response = await apiClient.get<{ data: AgentAssignment[] }>(
|
||||
`${BASE_URL}/microdao/${microdaoId}`
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all citywide assignments (DAARION108)
|
||||
*/
|
||||
export async function getCitywideAssignments(): Promise<AgentAssignment[]> {
|
||||
const response = await apiClient.get<{ data: AgentAssignment[] }>(
|
||||
`${BASE_URL}/citywide`
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get agent's effective scope
|
||||
*/
|
||||
export async function getAgentScope(agentId: string): Promise<AgentScope> {
|
||||
const response = await apiClient.get<{ data: AgentScope }>(
|
||||
`${BASE_URL}/agent/${agentId}/scope`
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if agent has assignment to target
|
||||
*/
|
||||
export async function checkAssignment(
|
||||
agentId: string,
|
||||
targetMicrodaoId: string
|
||||
): Promise<boolean> {
|
||||
const response = await apiClient.get<{ data: { hasAssignment: boolean } }>(
|
||||
`${BASE_URL}/check`,
|
||||
{ params: { agentId, targetMicrodaoId } }
|
||||
);
|
||||
return response.data.data.hasAssignment;
|
||||
}
|
||||
|
||||
// React Query hooks
|
||||
export const assignmentKeys = {
|
||||
all: ['assignments'] as const,
|
||||
agent: (agentId: string) => [...assignmentKeys.all, 'agent', agentId] as const,
|
||||
microdao: (microdaoId: string) => [...assignmentKeys.all, 'microdao', microdaoId] as const,
|
||||
citywide: () => [...assignmentKeys.all, 'citywide'] as const,
|
||||
scope: (agentId: string) => [...assignmentKeys.all, 'scope', agentId] as const,
|
||||
};
|
||||
|
||||
125
src/api/dais.ts
Normal file
125
src/api/dais.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* DAIS API Client
|
||||
* Based on: docs/foundation/DAARION_Identity_And_Access_Draft_v1.md
|
||||
*/
|
||||
|
||||
import { apiClient } from './client';
|
||||
import type { DaisProfile, DaisEmail, DaisWallet } from '../types/ontology';
|
||||
|
||||
const BASE_URL = '/api/v1/dais';
|
||||
|
||||
export interface CreateDaisRequest {
|
||||
email?: string;
|
||||
walletAddress?: string;
|
||||
network?: 'evm' | 'ton' | 'solana';
|
||||
}
|
||||
|
||||
export interface DaisCreationResult {
|
||||
identity: DaisProfile['identity'];
|
||||
agentId: string;
|
||||
matrixHandle: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DAIS identity
|
||||
*/
|
||||
export async function createDaisIdentity(
|
||||
request: CreateDaisRequest
|
||||
): Promise<DaisCreationResult> {
|
||||
const response = await apiClient.post<{ data: DaisCreationResult }>(
|
||||
`${BASE_URL}/identity`,
|
||||
request
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DAIS profile by ID
|
||||
*/
|
||||
export async function getDaisProfile(daisId: string): Promise<DaisProfile> {
|
||||
const response = await apiClient.get<{ data: DaisProfile }>(
|
||||
`${BASE_URL}/${daisId}`
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DAIS profile by agent ID
|
||||
*/
|
||||
export async function getDaisByAgent(agentId: string): Promise<DaisProfile> {
|
||||
const response = await apiClient.get<{ data: DaisProfile }>(
|
||||
`${BASE_URL}/agent/${agentId}`
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add email to DAIS
|
||||
*/
|
||||
export async function addEmail(
|
||||
daisId: string,
|
||||
email: string
|
||||
): Promise<DaisEmail> {
|
||||
const response = await apiClient.post<{ data: DaisEmail }>(
|
||||
`${BASE_URL}/${daisId}/email`,
|
||||
{ email }
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify email with OTP
|
||||
*/
|
||||
export async function verifyEmail(
|
||||
daisId: string,
|
||||
email: string,
|
||||
otp: string
|
||||
): Promise<void> {
|
||||
await apiClient.post(`${BASE_URL}/${daisId}/email/verify`, { email, otp });
|
||||
}
|
||||
|
||||
/**
|
||||
* Add wallet to DAIS
|
||||
*/
|
||||
export async function addWallet(
|
||||
daisId: string,
|
||||
walletAddress: string,
|
||||
network: 'evm' | 'ton' | 'solana' = 'evm'
|
||||
): Promise<DaisWallet> {
|
||||
const response = await apiClient.post<{ data: DaisWallet }>(
|
||||
`${BASE_URL}/${daisId}/wallet`,
|
||||
{ walletAddress, network }
|
||||
);
|
||||
return response.data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify wallet with SIWE signature
|
||||
*/
|
||||
export async function verifyWallet(
|
||||
daisId: string,
|
||||
walletAddress: string,
|
||||
signature: string,
|
||||
message: string
|
||||
): Promise<void> {
|
||||
await apiClient.post(`${BASE_URL}/${daisId}/wallet/verify`, {
|
||||
walletAddress,
|
||||
signature,
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote to orchestrator
|
||||
*/
|
||||
export async function promoteToOrchestrator(daisId: string): Promise<void> {
|
||||
await apiClient.post(`${BASE_URL}/${daisId}/promote-to-orchestrator`);
|
||||
}
|
||||
|
||||
// React Query hooks
|
||||
export const daisKeys = {
|
||||
all: ['dais'] as const,
|
||||
profile: (id: string) => [...daisKeys.all, 'profile', id] as const,
|
||||
byAgent: (agentId: string) => [...daisKeys.all, 'byAgent', agentId] as const,
|
||||
};
|
||||
|
||||
134
src/features/assignments/components/AssignmentsPanel.tsx
Normal file
134
src/features/assignments/components/AssignmentsPanel.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Agent Assignments Panel Component
|
||||
* Displays agent's assignments to other MicroDAOs
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getAgentAssignments, getAgentScope, assignmentKeys } from '../../../api/assignments';
|
||||
import type { AgentAssignment, AssignmentScope } from '../../../types/ontology';
|
||||
|
||||
interface AssignmentsPanelProps {
|
||||
agentId: string;
|
||||
}
|
||||
|
||||
const scopeColors: Record<AssignmentScope, string> = {
|
||||
microdao: 'bg-blue-500/20 text-blue-400 border-blue-500/30',
|
||||
district: 'bg-purple-500/20 text-purple-400 border-purple-500/30',
|
||||
city: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30',
|
||||
};
|
||||
|
||||
const scopeLabels: Record<AssignmentScope, string> = {
|
||||
microdao: 'MicroDAO',
|
||||
district: 'District',
|
||||
city: 'City',
|
||||
};
|
||||
|
||||
const roleLabels: Record<string, string> = {
|
||||
advisor: '💡 Advisor',
|
||||
security: '🔒 Security',
|
||||
mentor: '🎓 Mentor',
|
||||
ops: '⚙️ Ops',
|
||||
'core-team': '⭐ Core Team',
|
||||
member: '👤 Member',
|
||||
};
|
||||
|
||||
export function AssignmentsPanel({ agentId }: AssignmentsPanelProps) {
|
||||
const { data: assignments, isLoading: assignmentsLoading } = useQuery({
|
||||
queryKey: assignmentKeys.agent(agentId),
|
||||
queryFn: () => getAgentAssignments(agentId),
|
||||
});
|
||||
|
||||
const { data: scope, isLoading: scopeLoading } = useQuery({
|
||||
queryKey: assignmentKeys.scope(agentId),
|
||||
queryFn: () => getAgentScope(agentId),
|
||||
});
|
||||
|
||||
if (assignmentsLoading || scopeLoading) {
|
||||
return (
|
||||
<div className="bg-gray-800 rounded-lg p-4 animate-pulse">
|
||||
<div className="h-4 bg-gray-700 rounded w-3/4 mb-2"></div>
|
||||
<div className="h-3 bg-gray-700 rounded w-1/2"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-gray-800 border border-gray-700 rounded-lg p-4">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-white font-medium">Призначення агента</h3>
|
||||
{scope && (
|
||||
<span
|
||||
className={`px-2 py-0.5 rounded-full text-xs border ${
|
||||
scopeColors[scope.effectiveScope]
|
||||
}`}
|
||||
>
|
||||
Scope: {scopeLabels[scope.effectiveScope]}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Home MicroDAO */}
|
||||
{scope?.homeMicrodaoId && (
|
||||
<div className="mb-4 p-3 bg-gray-700/50 rounded-lg">
|
||||
<div className="text-xs text-gray-400 mb-1">Домашня MicroDAO</div>
|
||||
<div className="text-white font-medium">{scope.homeMicrodaoId}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Assignments List */}
|
||||
<div className="space-y-2">
|
||||
{assignments && assignments.length > 0 ? (
|
||||
assignments.map((assignment) => (
|
||||
<AssignmentCard key={assignment.id} assignment={assignment} />
|
||||
))
|
||||
) : (
|
||||
<div className="text-gray-400 text-sm text-center py-4">
|
||||
Немає активних призначень
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Add Assignment Button */}
|
||||
<button className="mt-4 w-full py-2 border border-dashed border-gray-600 rounded-lg text-gray-400 hover:text-gray-300 hover:border-gray-500 transition-colors text-sm">
|
||||
+ Додати призначення
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AssignmentCard({ assignment }: { assignment: AgentAssignment }) {
|
||||
return (
|
||||
<div className="p-3 bg-gray-700/30 rounded-lg border border-gray-600/50 hover:border-gray-500/50 transition-colors">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className={`px-2 py-0.5 rounded text-xs border ${
|
||||
scopeColors[assignment.scope]
|
||||
}`}
|
||||
>
|
||||
{scopeLabels[assignment.scope]}
|
||||
</span>
|
||||
<span className="text-white font-medium text-sm">
|
||||
{assignment.targetMicrodaoId}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-xs text-gray-400">
|
||||
{roleLabels[assignment.role] || assignment.role}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between text-xs text-gray-500">
|
||||
<span>
|
||||
Від: {new Date(assignment.startTs).toLocaleDateString('uk-UA')}
|
||||
</span>
|
||||
{assignment.endTs && (
|
||||
<span>
|
||||
До: {new Date(assignment.endTs).toLocaleDateString('uk-UA')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
138
src/features/dais/components/DaisProfileCard.tsx
Normal file
138
src/features/dais/components/DaisProfileCard.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* DAIS Profile Card Component
|
||||
* Displays DAIS identity information
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getDaisByAgent, daisKeys } from '../../../api/dais';
|
||||
import type { DaisProfile, DaisTrustLevel } from '../../../types/ontology';
|
||||
|
||||
interface DaisProfileCardProps {
|
||||
agentId: string;
|
||||
}
|
||||
|
||||
const trustLevelColors: Record<DaisTrustLevel, string> = {
|
||||
guest: 'bg-gray-500',
|
||||
agent: 'bg-blue-500',
|
||||
verified: 'bg-green-500',
|
||||
orchestrator: 'bg-purple-500',
|
||||
operator: 'bg-yellow-500',
|
||||
};
|
||||
|
||||
const trustLevelLabels: Record<DaisTrustLevel, string> = {
|
||||
guest: 'Гість',
|
||||
agent: 'Агент',
|
||||
verified: 'Верифікований',
|
||||
orchestrator: 'Оркестратор',
|
||||
operator: 'Оператор',
|
||||
};
|
||||
|
||||
export function DaisProfileCard({ agentId }: DaisProfileCardProps) {
|
||||
const { data: profile, isLoading, error } = useQuery({
|
||||
queryKey: daisKeys.byAgent(agentId),
|
||||
queryFn: () => getDaisByAgent(agentId),
|
||||
retry: false,
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="bg-gray-800 rounded-lg p-4 animate-pulse">
|
||||
<div className="h-4 bg-gray-700 rounded w-3/4 mb-2"></div>
|
||||
<div className="h-3 bg-gray-700 rounded w-1/2"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error || !profile) {
|
||||
return (
|
||||
<div className="bg-gray-800/50 border border-gray-700 rounded-lg p-4">
|
||||
<p className="text-gray-400 text-sm">DAIS профіль не знайдено</p>
|
||||
<button className="mt-2 text-blue-400 hover:text-blue-300 text-sm">
|
||||
+ Створити DAIS ідентичність
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-gray-800 border border-gray-700 rounded-lg p-4">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h3 className="text-white font-medium">DAIS Ідентичність</h3>
|
||||
<span
|
||||
className={`px-2 py-0.5 rounded-full text-xs text-white ${
|
||||
trustLevelColors[profile.identity.trustLevel]
|
||||
}`}
|
||||
>
|
||||
{trustLevelLabels[profile.identity.trustLevel]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 text-sm">
|
||||
{/* DID */}
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-400">DID</span>
|
||||
<code className="text-gray-300 text-xs bg-gray-700 px-2 py-0.5 rounded">
|
||||
{profile.identity.did.slice(0, 24)}...
|
||||
</code>
|
||||
</div>
|
||||
|
||||
{/* Matrix Handle */}
|
||||
{profile.identity.matrixHandle && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-gray-400">Matrix</span>
|
||||
<span className="text-green-400">{profile.identity.matrixHandle}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Emails */}
|
||||
<div className="mt-3">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<span className="text-gray-400">Email</span>
|
||||
<span className="text-gray-500 text-xs">{profile.emails.length}</span>
|
||||
</div>
|
||||
{profile.emails.map((email) => (
|
||||
<div
|
||||
key={email.id}
|
||||
className="flex items-center justify-between bg-gray-700/50 px-2 py-1 rounded"
|
||||
>
|
||||
<span className="text-gray-300 text-xs">{email.email}</span>
|
||||
{email.verified ? (
|
||||
<span className="text-green-400 text-xs">✓</span>
|
||||
) : (
|
||||
<span className="text-yellow-400 text-xs">⏳</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Wallets */}
|
||||
<div className="mt-3">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<span className="text-gray-400">Гаманці</span>
|
||||
<span className="text-gray-500 text-xs">{profile.wallets.length}</span>
|
||||
</div>
|
||||
{profile.wallets.map((wallet) => (
|
||||
<div
|
||||
key={wallet.id}
|
||||
className="flex items-center justify-between bg-gray-700/50 px-2 py-1 rounded"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs text-gray-500 uppercase">{wallet.network}</span>
|
||||
<span className="text-gray-300 text-xs">
|
||||
{wallet.walletAddress.slice(0, 6)}...{wallet.walletAddress.slice(-4)}
|
||||
</span>
|
||||
</div>
|
||||
{wallet.verified ? (
|
||||
<span className="text-green-400 text-xs">✓</span>
|
||||
) : (
|
||||
<span className="text-yellow-400 text-xs">⏳</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
156
src/features/ontology/components/OntologyBadge.tsx
Normal file
156
src/features/ontology/components/OntologyBadge.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Ontology Badge Components
|
||||
* Displays badges for MicroDAO type, Node status, Agent role, etc.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type {
|
||||
MicrodaoType,
|
||||
NodeStatus,
|
||||
NodeKind,
|
||||
AgentRole,
|
||||
ServiceScope
|
||||
} from '../../../types/ontology';
|
||||
|
||||
// ============================================================================
|
||||
// MicroDAO Type Badge
|
||||
// ============================================================================
|
||||
|
||||
const microdaoTypeConfig: Record<MicrodaoType, { label: string; color: string; icon: string }> = {
|
||||
root: { label: 'Root', color: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30', icon: '🏛️' },
|
||||
standard: { label: 'Standard', color: 'bg-blue-500/20 text-blue-400 border-blue-500/30', icon: '🏠' },
|
||||
district: { label: 'District', color: 'bg-purple-500/20 text-purple-400 border-purple-500/30', icon: '🏙️' },
|
||||
};
|
||||
|
||||
export function MicrodaoTypeBadge({ type }: { type: MicrodaoType }) {
|
||||
const config = microdaoTypeConfig[type];
|
||||
return (
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs border ${config.color}`}>
|
||||
<span>{config.icon}</span>
|
||||
<span>{config.label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Node Status Badge
|
||||
// ============================================================================
|
||||
|
||||
const nodeStatusConfig: Record<NodeStatus, { label: string; color: string; icon: string }> = {
|
||||
provisioning: { label: 'Provisioning', color: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30', icon: '⏳' },
|
||||
active: { label: 'Active', color: 'bg-green-500/20 text-green-400 border-green-500/30', icon: '✅' },
|
||||
draining: { label: 'Draining', color: 'bg-orange-500/20 text-orange-400 border-orange-500/30', icon: '🔄' },
|
||||
retired: { label: 'Retired', color: 'bg-gray-500/20 text-gray-400 border-gray-500/30', icon: '⛔' },
|
||||
};
|
||||
|
||||
export function NodeStatusBadge({ status }: { status: NodeStatus }) {
|
||||
const config = nodeStatusConfig[status];
|
||||
return (
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs border ${config.color}`}>
|
||||
<span>{config.icon}</span>
|
||||
<span>{config.label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Node Kind Badge
|
||||
// ============================================================================
|
||||
|
||||
const nodeKindConfig: Record<NodeKind, { label: string; icon: string }> = {
|
||||
smartphone: { label: 'Smartphone', icon: '📱' },
|
||||
laptop: { label: 'Laptop', icon: '💻' },
|
||||
edge: { label: 'Edge', icon: '📡' },
|
||||
datacenter: { label: 'Datacenter', icon: '🖥️' },
|
||||
iot: { label: 'IoT', icon: '🔌' },
|
||||
'gpu-cluster': { label: 'GPU Cluster', icon: '🎮' },
|
||||
};
|
||||
|
||||
export function NodeKindBadge({ kind }: { kind: NodeKind }) {
|
||||
const config = nodeKindConfig[kind];
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs bg-gray-700 text-gray-300 border border-gray-600">
|
||||
<span>{config.icon}</span>
|
||||
<span>{config.label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Agent Role Badge
|
||||
// ============================================================================
|
||||
|
||||
const agentRoleConfig: Record<AgentRole, { label: string; color: string; icon: string }> = {
|
||||
regular: { label: 'Regular', color: 'bg-blue-500/20 text-blue-400 border-blue-500/30', icon: '👤' },
|
||||
orchestrator: { label: 'Orchestrator', color: 'bg-purple-500/20 text-purple-400 border-purple-500/30', icon: '🎭' },
|
||||
};
|
||||
|
||||
export function AgentRoleBadge({ role }: { role: AgentRole }) {
|
||||
const config = agentRoleConfig[role];
|
||||
return (
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs border ${config.color}`}>
|
||||
<span>{config.icon}</span>
|
||||
<span>{config.label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Service Scope Badge
|
||||
// ============================================================================
|
||||
|
||||
const serviceScopeConfig: Record<ServiceScope, { label: string; color: string; icon: string }> = {
|
||||
microdao: { label: 'MicroDAO', color: 'bg-blue-500/20 text-blue-400 border-blue-500/30', icon: '🏠' },
|
||||
district: { label: 'District', color: 'bg-purple-500/20 text-purple-400 border-purple-500/30', icon: '🏙️' },
|
||||
city: { label: 'City', color: 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30', icon: '🌆' },
|
||||
};
|
||||
|
||||
export function ServiceScopeBadge({ scope }: { scope: ServiceScope }) {
|
||||
const config = serviceScopeConfig[scope];
|
||||
return (
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs border ${config.color}`}>
|
||||
<span>{config.icon}</span>
|
||||
<span>{config.label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Ontology Hierarchy Display
|
||||
// ============================================================================
|
||||
|
||||
interface OntologyPathProps {
|
||||
agentName?: string;
|
||||
microdaoName?: string;
|
||||
nodeName?: string;
|
||||
districtName?: string;
|
||||
}
|
||||
|
||||
export function OntologyPath({ agentName, microdaoName, nodeName, districtName }: OntologyPathProps) {
|
||||
return (
|
||||
<div className="flex items-center gap-1 text-xs text-gray-400">
|
||||
{agentName && (
|
||||
<>
|
||||
<span className="text-blue-400">👤 {agentName}</span>
|
||||
<span>→</span>
|
||||
</>
|
||||
)}
|
||||
{microdaoName && (
|
||||
<>
|
||||
<span className="text-purple-400">🏠 {microdaoName}</span>
|
||||
{(nodeName || districtName) && <span>→</span>}
|
||||
</>
|
||||
)}
|
||||
{nodeName && (
|
||||
<>
|
||||
<span className="text-green-400">🖥️ {nodeName}</span>
|
||||
{districtName && <span>→</span>}
|
||||
</>
|
||||
)}
|
||||
{districtName && (
|
||||
<span className="text-yellow-400">🏙️ {districtName}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
239
src/types/ontology.ts
Normal file
239
src/types/ontology.ts
Normal file
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* DAARION Ontology Types (Frontend)
|
||||
* Based on: docs/foundation/DAARION_Ontology_Core_v1.md
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// AGENT
|
||||
// ============================================================================
|
||||
|
||||
export type AgentRole = 'regular' | 'orchestrator';
|
||||
export type ServiceScope = 'microdao' | 'district' | 'city';
|
||||
|
||||
export interface Agent {
|
||||
id: string;
|
||||
name: string;
|
||||
kind: string;
|
||||
daisIdentityId?: string;
|
||||
homeMicrodaoId?: string;
|
||||
homeNodeId?: string;
|
||||
role: AgentRole;
|
||||
serviceScope?: ServiceScope;
|
||||
isOrchestrator: boolean;
|
||||
isPublic: boolean;
|
||||
visibilityScope?: string;
|
||||
primaryMicrodaoId?: string;
|
||||
nodeId?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export type AgentType = 'personal' | 'service' | 'core-city' | 'orchestrator';
|
||||
|
||||
// ============================================================================
|
||||
// DAIS - DAARION Autonomous Identity System
|
||||
// ============================================================================
|
||||
|
||||
export type DaisTrustLevel = 'guest' | 'agent' | 'verified' | 'orchestrator' | 'operator';
|
||||
|
||||
export interface DaisIdentity {
|
||||
id: string;
|
||||
did: string;
|
||||
defaultEmail?: string;
|
||||
defaultWallet?: string;
|
||||
matrixHandle?: string;
|
||||
trustLevel: DaisTrustLevel;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface DaisEmail {
|
||||
id: string;
|
||||
daisId: string;
|
||||
email: string;
|
||||
verified: boolean;
|
||||
verifiedAt?: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface DaisWallet {
|
||||
id: string;
|
||||
daisId: string;
|
||||
walletAddress: string;
|
||||
network: 'evm' | 'ton' | 'solana';
|
||||
verified: boolean;
|
||||
verifiedAt?: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface DaisProfile {
|
||||
identity: DaisIdentity;
|
||||
emails: DaisEmail[];
|
||||
wallets: DaisWallet[];
|
||||
keys: Array<{
|
||||
id: string;
|
||||
keyType: string;
|
||||
publicKey: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MICRODAO
|
||||
// ============================================================================
|
||||
|
||||
export type MicrodaoType = 'root' | 'standard' | 'district';
|
||||
|
||||
export interface Microdao {
|
||||
id: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
type: MicrodaoType;
|
||||
primaryOrchestratorAgentId?: string;
|
||||
parentMicrodaoId?: string;
|
||||
walletAddress?: string;
|
||||
ownerAgentId?: string;
|
||||
isPlatform: boolean;
|
||||
isActive: boolean;
|
||||
isPublic: boolean;
|
||||
district?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// NODE
|
||||
// ============================================================================
|
||||
|
||||
export type NodeKind =
|
||||
| 'smartphone'
|
||||
| 'laptop'
|
||||
| 'edge'
|
||||
| 'datacenter'
|
||||
| 'iot'
|
||||
| 'gpu-cluster';
|
||||
|
||||
export type NodeStatus =
|
||||
| 'provisioning'
|
||||
| 'active'
|
||||
| 'draining'
|
||||
| 'retired';
|
||||
|
||||
export interface NodeCapabilities {
|
||||
cpu?: string;
|
||||
ram?: string;
|
||||
gpu?: {
|
||||
name: string;
|
||||
vram?: string;
|
||||
unified_memory_gb?: number;
|
||||
};
|
||||
network?: {
|
||||
up: string;
|
||||
down: string;
|
||||
};
|
||||
sensors?: string[];
|
||||
modules?: Array<{
|
||||
id: string;
|
||||
status: string;
|
||||
port?: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
id: string;
|
||||
nodeId: string;
|
||||
name: string;
|
||||
microdaoId?: string;
|
||||
kind: NodeKind;
|
||||
status: NodeStatus;
|
||||
capabilities: NodeCapabilities;
|
||||
lastHeartbeat?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// AGENT ASSIGNMENT
|
||||
// ============================================================================
|
||||
|
||||
export type AssignmentScope = 'microdao' | 'district' | 'city';
|
||||
export type AssignmentRole = 'advisor' | 'security' | 'mentor' | 'ops' | 'core-team' | 'member';
|
||||
|
||||
export interface AgentAssignment {
|
||||
id: string;
|
||||
agentId: string;
|
||||
agentName?: string;
|
||||
targetMicrodaoId: string;
|
||||
scope: AssignmentScope;
|
||||
role: AssignmentRole | string;
|
||||
startTs: string;
|
||||
endTs?: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface AgentScope {
|
||||
homeMicrodaoId: string | null;
|
||||
assignments: AgentAssignment[];
|
||||
effectiveScope: AssignmentScope;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ROOMS LAYER
|
||||
// ============================================================================
|
||||
|
||||
export type RoomType =
|
||||
| 'city-room'
|
||||
| 'dao-room'
|
||||
| 'front-room'
|
||||
| 'agent-room'
|
||||
| 'event-room'
|
||||
| 'district-room';
|
||||
|
||||
export type RoomVisibility =
|
||||
| 'private'
|
||||
| 'members'
|
||||
| 'public-city'
|
||||
| 'public-global';
|
||||
|
||||
export type SpaceScope = 'city' | 'microdao' | 'district';
|
||||
|
||||
export interface Room {
|
||||
id: string;
|
||||
ownerType: 'city' | 'microdao' | 'district' | 'agent';
|
||||
ownerId: string;
|
||||
type: RoomType;
|
||||
spaceScope: SpaceScope;
|
||||
visibility: RoomVisibility;
|
||||
name: string;
|
||||
description?: string;
|
||||
matrixRoomId?: string;
|
||||
isPortal: boolean;
|
||||
portalTargetMicrodaoId?: string;
|
||||
mapX?: number;
|
||||
mapY?: number;
|
||||
zone?: string;
|
||||
primaryAgentId?: string;
|
||||
teamAgentIds?: string[];
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ONTOLOGY HIERARCHY DISPLAY
|
||||
// ============================================================================
|
||||
|
||||
export interface OntologyHierarchy {
|
||||
agent: Agent;
|
||||
dais?: DaisProfile;
|
||||
homeMicrodao?: Microdao;
|
||||
homeNode?: Node;
|
||||
assignments: AgentAssignment[];
|
||||
effectiveScope: AssignmentScope;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user