feat(governance): Governance Engine MVP implementation

- Backend:
  - Migration 032: agent_gov_level, status, incidents, permissions tables
  - Domain types for governance layer
  - Permission Engine with all governance checks
  - Governance Service (promote/demote/roles)
  - Revocation Service (revoke/suspend/reinstate)
  - Audit Service (events filtering and stats)
  - Incidents Service (create/assign/escalate/resolve)
  - REST API routes for governance, audit, incidents

- Frontend:
  - TypeScript types for governance
  - API clients for governance, audit, incidents
  - GovernanceLevelBadge component
  - CityGovernancePanel component
  - AuditDashboard component
  - IncidentsList component with detail modal

Based on: Agent_Governance_Protocol_v1.md
This commit is contained in:
Apple
2025-11-29 16:02:06 -08:00
parent 2627205663
commit e233d32ae7
20 changed files with 5837 additions and 0 deletions

View File

@@ -0,0 +1,328 @@
/**
* Governance Types
* Based on: docs/foundation/Agent_Governance_Protocol_v1.md
*
* Implements the 8-level agent hierarchy and permission system
*/
// ============================================================================
// GOVERNANCE LEVELS (0-7)
// ============================================================================
export const AGENT_LEVELS = {
GUEST: 0,
PERSONAL: 1,
MEMBER: 2,
WORKER: 3,
CORE_TEAM: 4,
ORCHESTRATOR: 5,
DISTRICT_LEAD: 6,
CITY_GOVERNANCE: 7,
} as const;
export type AgentLevelNum = typeof AGENT_LEVELS[keyof typeof AGENT_LEVELS];
export type AgentGovLevel =
| 'guest'
| 'personal'
| 'member'
| 'worker'
| 'core_team'
| 'orchestrator'
| 'district_lead'
| 'city_governance';
export const GOV_LEVEL_TO_NUM: Record<AgentGovLevel, AgentLevelNum> = {
guest: 0,
personal: 1,
member: 2,
worker: 3,
core_team: 4,
orchestrator: 5,
district_lead: 6,
city_governance: 7,
};
export const NUM_TO_GOV_LEVEL: Record<AgentLevelNum, AgentGovLevel> = {
0: 'guest',
1: 'personal',
2: 'member',
3: 'worker',
4: 'core_team',
5: 'orchestrator',
6: 'district_lead',
7: 'city_governance',
};
// ============================================================================
// AGENT STATUS
// ============================================================================
export type AgentStatus = 'active' | 'suspended' | 'revoked';
// ============================================================================
// GOVERNANCE POWERS
// ============================================================================
export type GovernancePower =
| 'administrative' // Create/close DAO/Nodes/Rooms
| 'moderation' // Ban, mute, moderate rooms
| 'execution' // Execute tasks on behalf of DAO
| 'infrastructure' // Control node resources, deploy
| 'identity' // Issue/revoke DAIS keys
| 'protocol' // Change system rules (City only)
| 'district'; // Manage subordinate DAOs
export interface PowerMatrix {
level: AgentGovLevel;
powers: GovernancePower[];
}
export const POWER_MATRIX: PowerMatrix[] = [
{ level: 'guest', powers: [] },
{ level: 'personal', powers: ['execution'] },
{ level: 'member', powers: ['execution'] },
{ level: 'worker', powers: ['execution', 'moderation'] },
{ level: 'core_team', powers: ['administrative', 'moderation', 'execution', 'infrastructure'] },
{ level: 'orchestrator', powers: ['administrative', 'moderation', 'execution', 'infrastructure', 'identity'] },
{ level: 'district_lead', powers: ['administrative', 'moderation', 'execution', 'infrastructure', 'identity', 'district'] },
{ level: 'city_governance', powers: ['administrative', 'moderation', 'execution', 'infrastructure', 'identity', 'protocol', 'district'] },
];
// ============================================================================
// PERMISSIONS
// ============================================================================
export type PermissionAction = 'read' | 'write' | 'moderate' | 'admin' | 'superadmin';
export type TargetType = 'room' | 'microdao' | 'node' | 'district' | 'city';
export interface Permission {
id: string;
daisId: string;
targetType: TargetType;
targetId: string;
action: PermissionAction;
grantedBy: string;
expiresAt?: Date;
metadata: Record<string, unknown>;
createdAt: Date;
}
export interface CheckPermissionRequest {
daisId: string;
targetType: TargetType;
targetId: string;
action: PermissionAction;
}
export interface GrantPermissionRequest {
daisId: string;
targetType: TargetType;
targetId: string;
action: PermissionAction;
grantedBy: string;
expiresAt?: Date;
metadata?: Record<string, unknown>;
}
// ============================================================================
// GOVERNANCE ACTIONS
// ============================================================================
export interface PromoteAgentRequest {
actorId: string; // Who is performing the action
targetId: string; // Agent being promoted
newLevel: AgentGovLevel;
scope: GovernanceScope;
reason?: string;
}
export interface RevokeAgentRequest {
actorId: string;
targetId: string;
reason: string;
scope: GovernanceScope;
revocationType: RevocationType;
}
export interface AssignAgentRequest {
actorId: string;
targetId: string;
scopeType: 'microdao' | 'district' | 'city';
scopeId: string;
role: string;
}
export type GovernanceScope = 'city' | `district:${string}` | `microdao:${string}` | `node:${string}`;
// ============================================================================
// REVOCATION
// ============================================================================
export type RevocationType = 'soft' | 'hard' | 'shadow';
export interface RevocationEffect {
daisKeysInvalidated: boolean;
walletSigningDisabled: boolean;
roomAccessRevoked: boolean;
nodePrivilegesRemoved: boolean;
assignmentsTerminated: boolean;
}
export interface AgentRevocation {
id: string;
agentId: string;
daisId?: string;
revokedBy: string;
revocationType: RevocationType;
reason: string;
scope: GovernanceScope;
keysInvalidated: boolean;
walletDisabled: boolean;
roomAccessRevoked: boolean;
nodePrivilegesRemoved: boolean;
assignmentsTerminated: boolean;
reversible: boolean;
reversedAt?: Date;
reversedBy?: string;
createdAt: Date;
}
// ============================================================================
// INCIDENTS & ESCALATION
// ============================================================================
export type IncidentStatus = 'open' | 'in_progress' | 'resolved' | 'closed';
export type IncidentPriority = 'low' | 'medium' | 'high' | 'critical';
export type EscalationLevel = 'microdao' | 'district' | 'city';
export type TargetScopeType = 'city' | 'district' | 'microdao' | 'room' | 'node' | 'agent';
export interface Incident {
id: string;
createdByDaisId: string;
targetScopeType: TargetScopeType;
targetScopeId: string;
status: IncidentStatus;
priority: IncidentPriority;
assignedToDaisId?: string;
escalationLevel: EscalationLevel;
title: string;
description?: string;
resolution?: string;
metadata: Record<string, unknown>;
createdAt: Date;
updatedAt: Date;
resolvedAt?: Date;
closedAt?: Date;
}
export interface CreateIncidentRequest {
createdByDaisId: string;
targetScopeType: TargetScopeType;
targetScopeId: string;
priority?: IncidentPriority;
title: string;
description?: string;
metadata?: Record<string, unknown>;
}
export interface AssignIncidentRequest {
incidentId: string;
assignedToDaisId: string;
actorDaisId: string;
}
export interface EscalateIncidentRequest {
incidentId: string;
newLevel: EscalationLevel;
actorDaisId: string;
reason?: string;
}
export interface ResolveIncidentRequest {
incidentId: string;
resolution: string;
actorDaisId: string;
}
export interface IncidentHistory {
id: string;
incidentId: string;
action: 'created' | 'assigned' | 'escalated' | 'resolved' | 'closed' | 'comment';
actorDaisId: string;
oldValue?: Record<string, unknown>;
newValue?: Record<string, unknown>;
comment?: string;
createdAt: Date;
}
// ============================================================================
// AUDIT EVENTS
// ============================================================================
export type GovernanceEventType =
| 'agent.promoted'
| 'agent.demoted'
| 'agent.revoked'
| 'agent.reinstated'
| 'agent.assigned'
| 'agent.unassigned'
| 'permission.granted'
| 'permission.revoked'
| 'incident.created'
| 'incident.assigned'
| 'incident.escalated'
| 'incident.resolved'
| 'incident.closed'
| 'microdao.created'
| 'district.created'
| 'node.registered'
| 'room.created'
| 'room.published_to_city';
export interface GovernanceEvent {
id: string;
eventType: GovernanceEventType;
subject: string;
actorId: string;
targetId: string;
scope: GovernanceScope;
payload: Record<string, unknown>;
version: string;
status: 'pending' | 'published' | 'failed';
createdAt: Date;
publishedAt?: Date;
}
export interface AuditEventFilter {
eventType?: GovernanceEventType;
actorId?: string;
targetId?: string;
scope?: GovernanceScope;
createdAtFrom?: Date;
createdAtTo?: Date;
limit?: number;
offset?: number;
}
// ============================================================================
// GOVERNANCE CONTEXT
// ============================================================================
export interface GovernanceContext {
actorDaisId: string;
actorAgentId: string;
actorLevel: AgentGovLevel;
actorPowers: GovernancePower[];
currentScope: GovernanceScope;
microdaoId?: string;
districtId?: string;
}
export interface CanDoResult {
allowed: boolean;
reason?: string;
requiredLevel?: AgentGovLevel;
requiredPower?: GovernancePower;
}