@clduab11/gemini-flow
Version:
Revolutionary AI agent swarm coordination platform with Google Services integration, multimedia processing, and production-ready monitoring. Features 8 Google AI services, quantum computing capabilities, and enterprise-grade security.
1,635 lines (1,446 loc) • 46.2 kB
text/typescript
/**
* Quarantine and Recovery System for A2A Protocol
*
* Implements comprehensive quarantine and recovery mechanisms for
* compromised agents, providing secure isolation, rehabilitation
* challenges, and graduated recovery processes.
*
* Features:
* - Multi-level quarantine isolation (soft, hard, complete)
* - Progressive recovery challenges and verification
* - Behavioral rehabilitation programs
* - Automated recovery monitoring and assessment
* - Economic incentives and penalties for recovery
* - Distributed consensus for quarantine and recovery decisions
*/
import { EventEmitter } from "events";
import crypto from "crypto";
import { Logger } from "../../../utils/logger.js";
import { A2AIdentity, A2AMessage } from "../../../core/a2a-security-manager.js";
import { MaliciousDetectionResult } from "./malicious-detection.js";
import { ReputationScore } from "./reputation-system.js";
export interface QuarantineLevel {
level: "observation" | "soft" | "hard" | "complete";
name: string;
description: string;
restrictions: {
messageRateLimit: number; // Messages per minute
allowedOperations: string[]; // Allowed operations
networkAccess: boolean; // Network access allowed
consensusParticipation: boolean; // Can participate in consensus
peerInteraction: boolean; // Can interact with other agents
resourceAccess: string[]; // Allowed resources
};
duration: {
minimum: number; // Minimum quarantine time (ms)
maximum: number; // Maximum quarantine time (ms)
extendable: boolean; // Can be extended
};
recoveryRequirements: {
challengesRequired: number; // Number of challenges to complete
peerEndorsements: number; // Peer endorsements needed
behaviorScore: number; // Minimum behavior score
proofOfWork: boolean; // Requires proof of work
economicStake: number; // Economic stake required
};
}
export interface QuarantineRecord {
agentId: string;
quarantineId: string;
level: QuarantineLevel["level"];
startTime: Date;
endTime?: Date;
reason: string;
evidence: any;
detectionResult: MaliciousDetectionResult;
// Status tracking
status: "active" | "suspended" | "recovered" | "escalated" | "permanent";
extensions: QuarantineExtension[];
violations: QuarantineViolation[];
// Recovery progress
recoveryProgress: {
challengesCompleted: number;
challengesFailed: number;
peerEndorsements: number;
behaviorScore: number;
stakePledged: number;
recoveryAttempts: number;
};
// Monitoring data
monitoring: {
activityLevel: number;
complianceScore: number;
communicationPatterns: any[];
resourceUsage: any[];
lastActivity: Date;
};
metadata: {
createdBy: string;
approvedBy: string[];
reviewedBy: string[];
lastUpdated: Date;
notes: string[];
};
}
export interface QuarantineExtension {
extensionId: string;
reason: string;
additionalTime: number; // Additional time in ms
requestedBy: string;
approvedBy: string[];
timestamp: Date;
evidence: any;
}
export interface QuarantineViolation {
violationId: string;
type:
| "access_attempt"
| "rate_limit_exceeded"
| "unauthorized_operation"
| "malicious_activity";
description: string;
timestamp: Date;
evidence: any;
severity: "minor" | "moderate" | "severe" | "critical";
penalty: {
timeExtension?: number; // Additional quarantine time
levelEscalation?: boolean; // Escalate quarantine level
economicPenalty?: number; // Economic penalty
};
}
export interface RecoveryChallenge {
challengeId: string;
agentId: string;
type:
| "behavioral_compliance"
| "security_audit"
| "peer_collaboration"
| "proof_of_work"
| "skill_demonstration";
name: string;
description: string;
requirements: any;
timeLimit: number;
maxAttempts: number;
// Scoring
passingScore: number;
weight: number; // Weight in overall recovery score
// Status
status: "pending" | "in_progress" | "completed" | "failed" | "expired";
attempts: ChallengeAttempt[];
// Results
finalScore?: number;
completedAt?: Date;
evidence?: any;
reviewedBy?: string[];
}
export interface ChallengeAttempt {
attemptId: string;
startTime: Date;
endTime?: Date;
response: any;
score: number;
feedback: string;
reviewedBy: string;
evidence: any;
}
export interface PeerEndorsement {
endorsementId: string;
fromAgentId: string;
toAgentId: string;
type: "character" | "technical" | "trustworthiness" | "rehabilitation";
strength: "weak" | "moderate" | "strong";
message?: string;
evidence?: any;
timestamp: Date;
signature: string;
// Validation
validated: boolean;
validatedBy?: string;
weight: number; // Weight based on endorser's reputation
}
export interface RecoveryPlan {
planId: string;
agentId: string;
targetLevel: QuarantineLevel["level"] | "full_recovery";
estimatedDuration: number;
phases: RecoveryPhase[];
requirements: {
totalChallenges: number;
minimumScore: number;
peerEndorsements: number;
behaviorThreshold: number;
economicStake: number;
};
progress: {
currentPhase: number;
overallProgress: number; // 0-1
phasesCompleted: number;
challengesCompleted: number;
endorsementsReceived: number;
};
status: "draft" | "active" | "paused" | "completed" | "failed";
createdAt: Date;
lastUpdated: Date;
}
export interface RecoveryPhase {
phaseId: string;
name: string;
description: string;
order: number;
duration: number;
challenges: string[]; // Challenge IDs
requirements: {
minChallengeScore: number;
requiredEndorsements: number;
behaviorThreshold: number;
noViolations: boolean;
};
status: "pending" | "active" | "completed" | "failed";
startedAt?: Date;
completedAt?: Date;
}
export class QuarantineRecoveryManager extends EventEmitter {
private logger: Logger;
private quarantineLevels: Map<string, QuarantineLevel> = new Map();
private quarantineRecords: Map<string, QuarantineRecord> = new Map(); // agentId -> record
private recoveryChallenges: Map<string, RecoveryChallenge> = new Map(); // challengeId -> challenge
private peerEndorsements: Map<string, PeerEndorsement[]> = new Map(); // agentId -> endorsements
private recoveryPlans: Map<string, RecoveryPlan> = new Map(); // agentId -> plan
// Monitoring and assessment
private behaviorMonitor: BehaviorMonitor;
private recoveryAssessor: RecoveryAssessor;
private challengeValidator: ChallengeValidator;
private endorsementValidator: EndorsementValidator;
// Configuration
private config = {
quarantine: {
defaultLevel: "soft" as const,
maxExtensions: 3,
escalationThreshold: 3, // Violations before escalation
permanentThreshold: 10, // Violations before permanent ban
reviewInterval: 3600000, // 1 hour review interval
},
recovery: {
maxAttempts: 3,
challengeTimeout: 3600000, // 1 hour per challenge
endorsementValidityPeriod: 2592000000, // 30 days
minimumRecoveryTime: 86400000, // 24 hours minimum
maxRecoveryTime: 2592000000, // 30 days maximum
},
monitoring: {
activityThreshold: 0.1, // Minimum activity level
complianceThreshold: 0.8, // Minimum compliance score
assessmentInterval: 1800000, // 30 minutes
violationGracePeriod: 300000, // 5 minutes grace period
},
};
constructor() {
super();
this.logger = new Logger("QuarantineRecoveryManager");
this.initializeQuarantineLevels();
this.initializeComponents();
this.startMonitoring();
this.logger.info("Quarantine Recovery Manager initialized", {
features: [
"multi-level-quarantine",
"progressive-recovery",
"behavioral-rehabilitation",
"peer-endorsements",
"economic-incentives",
"automated-monitoring",
],
levels: Array.from(this.quarantineLevels.keys()),
});
}
/**
* Initialize quarantine levels
*/
private initializeQuarantineLevels(): void {
// Observation Level - Minimal restrictions
this.quarantineLevels.set("observation", {
level: "observation",
name: "Observation",
description: "Monitoring with minimal restrictions",
restrictions: {
messageRateLimit: 50,
allowedOperations: ["read", "status", "query"],
networkAccess: true,
consensusParticipation: true,
peerInteraction: true,
resourceAccess: ["public", "shared"],
},
duration: {
minimum: 3600000, // 1 hour
maximum: 86400000, // 24 hours
extendable: true,
},
recoveryRequirements: {
challengesRequired: 1,
peerEndorsements: 1,
behaviorScore: 0.6,
proofOfWork: false,
economicStake: 0,
},
});
// Soft Quarantine - Moderate restrictions
this.quarantineLevels.set("soft", {
level: "soft",
name: "Soft Quarantine",
description: "Limited operations with monitoring",
restrictions: {
messageRateLimit: 20,
allowedOperations: ["read", "status"],
networkAccess: true,
consensusParticipation: false,
peerInteraction: true,
resourceAccess: ["public"],
},
duration: {
minimum: 86400000, // 24 hours
maximum: 604800000, // 7 days
extendable: true,
},
recoveryRequirements: {
challengesRequired: 3,
peerEndorsements: 2,
behaviorScore: 0.7,
proofOfWork: true,
economicStake: 1000,
},
});
// Hard Quarantine - Severe restrictions
this.quarantineLevels.set("hard", {
level: "hard",
name: "Hard Quarantine",
description: "Severe restrictions with supervised access",
restrictions: {
messageRateLimit: 5,
allowedOperations: ["status"],
networkAccess: false,
consensusParticipation: false,
peerInteraction: false,
resourceAccess: [],
},
duration: {
minimum: 604800000, // 7 days
maximum: 2592000000, // 30 days
extendable: true,
},
recoveryRequirements: {
challengesRequired: 5,
peerEndorsements: 5,
behaviorScore: 0.8,
proofOfWork: true,
economicStake: 5000,
},
});
// Complete Isolation - Total isolation
this.quarantineLevels.set("complete", {
level: "complete",
name: "Complete Isolation",
description: "Total isolation from the system",
restrictions: {
messageRateLimit: 0,
allowedOperations: [],
networkAccess: false,
consensusParticipation: false,
peerInteraction: false,
resourceAccess: [],
},
duration: {
minimum: 2592000000, // 30 days
maximum: 7776000000, // 90 days
extendable: false,
},
recoveryRequirements: {
challengesRequired: 10,
peerEndorsements: 10,
behaviorScore: 0.9,
proofOfWork: true,
economicStake: 10000,
},
});
}
/**
* Initialize monitoring components
*/
private initializeComponents(): void {
this.behaviorMonitor = new BehaviorMonitor(this.config);
this.recoveryAssessor = new RecoveryAssessor(this.config);
this.challengeValidator = new ChallengeValidator(this.config);
this.endorsementValidator = new EndorsementValidator(this.config);
}
/**
* Start monitoring loops
*/
private startMonitoring(): void {
// Monitor quarantined agents
setInterval(async () => {
await this.monitorQuarantinedAgents();
}, this.config.monitoring.assessmentInterval);
// Review quarantine status
setInterval(async () => {
await this.reviewQuarantineStatus();
}, this.config.quarantine.reviewInterval);
// Process recovery challenges
setInterval(async () => {
await this.processRecoveryChallenges();
}, 60000); // Every minute
}
/**
* Quarantine an agent
*/
async quarantineAgent(
agentId: string,
level: QuarantineLevel["level"],
reason: string,
evidence: any,
detectionResult: MaliciousDetectionResult,
createdBy: string = "system",
): Promise<QuarantineRecord> {
const existingRecord = this.quarantineRecords.get(agentId);
if (existingRecord && existingRecord.status === "active") {
// Escalate existing quarantine
return await this.escalateQuarantine(agentId, level, reason, evidence);
}
const quarantineLevel = this.quarantineLevels.get(level);
if (!quarantineLevel) {
throw new Error(`Invalid quarantine level: ${level}`);
}
const record: QuarantineRecord = {
agentId,
quarantineId: crypto.randomUUID(),
level,
startTime: new Date(),
reason,
evidence,
detectionResult,
status: "active",
extensions: [],
violations: [],
recoveryProgress: {
challengesCompleted: 0,
challengesFailed: 0,
peerEndorsements: 0,
behaviorScore: 0.0,
stakePledged: 0,
recoveryAttempts: 0,
},
monitoring: {
activityLevel: 0,
complianceScore: 1.0,
communicationPatterns: [],
resourceUsage: [],
lastActivity: new Date(),
},
metadata: {
createdBy,
approvedBy: [createdBy],
reviewedBy: [],
lastUpdated: new Date(),
notes: [`Initial quarantine: ${reason}`],
},
};
this.quarantineRecords.set(agentId, record);
// Create recovery plan
const recoveryPlan = await this.createRecoveryPlan(
agentId,
quarantineLevel,
);
this.recoveryPlans.set(agentId, recoveryPlan);
// Schedule automatic review
this.scheduleQuarantineReview(agentId, quarantineLevel.duration.minimum);
this.logger.error("Agent quarantined", {
agentId,
level,
reason,
quarantineId: record.quarantineId,
duration: `${quarantineLevel.duration.minimum}ms - ${quarantineLevel.duration.maximum}ms`,
});
this.emit("agent_quarantined", {
agentId,
record,
recoveryPlan,
});
return record;
}
/**
* Create recovery plan for quarantined agent
*/
private async createRecoveryPlan(
agentId: string,
quarantineLevel: QuarantineLevel,
): Promise<RecoveryPlan> {
const phases = this.generateRecoveryPhases(quarantineLevel);
const plan: RecoveryPlan = {
planId: crypto.randomUUID(),
agentId,
targetLevel: "full_recovery",
estimatedDuration: this.calculateRecoveryDuration(quarantineLevel),
phases,
requirements: {
totalChallenges:
quarantineLevel.recoveryRequirements.challengesRequired,
minimumScore: 0.8,
peerEndorsements: quarantineLevel.recoveryRequirements.peerEndorsements,
behaviorThreshold: quarantineLevel.recoveryRequirements.behaviorScore,
economicStake: quarantineLevel.recoveryRequirements.economicStake,
},
progress: {
currentPhase: 0,
overallProgress: 0,
phasesCompleted: 0,
challengesCompleted: 0,
endorsementsReceived: 0,
},
status: "active",
createdAt: new Date(),
lastUpdated: new Date(),
};
// Generate challenges for each phase
for (const phase of phases) {
const challenges = await this.generatePhaseChallenges(
agentId,
phase,
quarantineLevel,
);
phase.challenges = challenges.map((c) => c.challengeId);
// Store challenges
challenges.forEach((challenge) => {
this.recoveryChallenges.set(challenge.challengeId, challenge);
});
}
return plan;
}
/**
* Submit recovery challenge response
*/
async submitChallengeResponse(
challengeId: string,
agentId: string,
response: any,
): Promise<{ success: boolean; score: number; feedback: string }> {
const challenge = this.recoveryChallenges.get(challengeId);
const record = this.quarantineRecords.get(agentId);
if (!challenge || !record || challenge.agentId !== agentId) {
throw new Error("Invalid challenge or agent not quarantined");
}
if (challenge.status !== "pending" && challenge.status !== "in_progress") {
throw new Error(`Challenge cannot be submitted: ${challenge.status}`);
}
// Check attempt limits
if (challenge.attempts.length >= challenge.maxAttempts) {
throw new Error("Maximum attempts exceeded");
}
// Mark as in progress
challenge.status = "in_progress";
const attempt: ChallengeAttempt = {
attemptId: crypto.randomUUID(),
startTime: new Date(),
response,
score: 0,
feedback: "",
reviewedBy: "system",
evidence: {},
};
try {
// Validate and score the response
const validation = await this.challengeValidator.validateResponse(
challenge,
response,
);
attempt.score = validation.score;
attempt.feedback = validation.feedback;
attempt.evidence = validation.evidence;
attempt.endTime = new Date();
challenge.attempts.push(attempt);
if (validation.score >= challenge.passingScore) {
// Challenge passed
challenge.status = "completed";
challenge.finalScore = validation.score;
challenge.completedAt = new Date();
// Update recovery progress
record.recoveryProgress.challengesCompleted++;
// Check if phase is complete
await this.checkPhaseCompletion(agentId);
this.logger.info("Recovery challenge completed", {
agentId,
challengeId,
score: validation.score,
type: challenge.type,
});
this.emit("challenge_completed", {
agentId,
challenge,
attempt,
validation,
});
return {
success: true,
score: validation.score,
feedback: validation.feedback,
};
} else {
// Challenge failed
if (challenge.attempts.length >= challenge.maxAttempts) {
challenge.status = "failed";
record.recoveryProgress.challengesFailed++;
this.logger.warn("Recovery challenge failed permanently", {
agentId,
challengeId,
attempts: challenge.attempts.length,
maxAttempts: challenge.maxAttempts,
});
}
return {
success: false,
score: validation.score,
feedback: validation.feedback,
};
}
} catch (error) {
attempt.endTime = new Date();
attempt.feedback = `Validation error: ${error.message}`;
challenge.attempts.push(attempt);
challenge.status = "pending"; // Allow retry
this.logger.error("Challenge validation failed", {
agentId,
challengeId,
error,
});
throw error;
}
}
/**
* Submit peer endorsement
*/
async submitPeerEndorsement(
fromAgentId: string,
toAgentId: string,
type: "character" | "technical" | "trustworthiness" | "rehabilitation",
strength: "weak" | "moderate" | "strong",
message?: string,
evidence?: any,
): Promise<boolean> {
const record = this.quarantineRecords.get(toAgentId);
if (!record || record.status !== "active") {
throw new Error("Agent not in active quarantine");
}
// Validate endorser
const isValidEndorser = await this.endorsementValidator.validateEndorser(
fromAgentId,
toAgentId,
);
if (!isValidEndorser) {
this.logger.warn("Invalid endorser", { fromAgentId, toAgentId });
return false;
}
const endorsement: PeerEndorsement = {
endorsementId: crypto.randomUUID(),
fromAgentId,
toAgentId,
type,
strength,
message,
evidence,
timestamp: new Date(),
signature: await this.signEndorsement(
fromAgentId,
toAgentId,
type,
strength,
),
validated: true,
validatedBy: "system",
weight: await this.calculateEndorsementWeight(fromAgentId),
};
// Store endorsement
const endorsements = this.peerEndorsements.get(toAgentId) || [];
endorsements.push(endorsement);
this.peerEndorsements.set(toAgentId, endorsements);
// Update recovery progress
record.recoveryProgress.peerEndorsements++;
this.logger.info("Peer endorsement submitted", {
fromAgent: fromAgentId,
toAgent: toAgentId,
type,
strength,
weight: endorsement.weight,
});
this.emit("peer_endorsement", endorsement);
return true;
}
/**
* Check agent's recovery eligibility
*/
async checkRecoveryEligibility(agentId: string): Promise<{
eligible: boolean;
progress: number;
missingRequirements: string[];
estimatedTimeRemaining: number;
}> {
const record = this.quarantineRecords.get(agentId);
const plan = this.recoveryPlans.get(agentId);
if (!record || !plan) {
return {
eligible: false,
progress: 0,
missingRequirements: ["Agent not in quarantine"],
estimatedTimeRemaining: 0,
};
}
const quarantineLevel = this.quarantineLevels.get(record.level)!;
const requirements = quarantineLevel.recoveryRequirements;
const progress = record.recoveryProgress;
const missingRequirements: string[] = [];
// Check minimum time requirement
const timeInQuarantine = Date.now() - record.startTime.getTime();
if (timeInQuarantine < quarantineLevel.duration.minimum) {
missingRequirements.push(
`Minimum time not met (${Math.ceil((quarantineLevel.duration.minimum - timeInQuarantine) / 3600000)} hours remaining)`,
);
}
// Check challenge requirements
if (progress.challengesCompleted < requirements.challengesRequired) {
missingRequirements.push(
`Challenges: ${progress.challengesCompleted}/${requirements.challengesRequired}`,
);
}
// Check peer endorsements
if (progress.peerEndorsements < requirements.peerEndorsements) {
missingRequirements.push(
`Endorsements: ${progress.peerEndorsements}/${requirements.peerEndorsements}`,
);
}
// Check behavior score
if (progress.behaviorScore < requirements.behaviorScore) {
missingRequirements.push(
`Behavior score: ${progress.behaviorScore.toFixed(2)}/${requirements.behaviorScore}`,
);
}
// Check economic stake
if (
requirements.economicStake > 0 &&
progress.stakePledged < requirements.economicStake
) {
missingRequirements.push(
`Stake: ${progress.stakePledged}/${requirements.economicStake}`,
);
}
const overallProgress = this.calculateRecoveryProgress(
record,
requirements,
);
const eligible = missingRequirements.length === 0;
let estimatedTimeRemaining = 0;
if (!eligible) {
estimatedTimeRemaining = Math.max(
0,
quarantineLevel.duration.minimum - timeInQuarantine,
);
}
return {
eligible,
progress: overallProgress,
missingRequirements,
estimatedTimeRemaining,
};
}
/**
* Process recovery request
*/
async processRecoveryRequest(agentId: string): Promise<{
approved: boolean;
newLevel?: QuarantineLevel["level"] | "full_recovery";
reason: string;
conditions?: string[];
}> {
const eligibility = await this.checkRecoveryEligibility(agentId);
if (!eligibility.eligible) {
return {
approved: false,
reason: `Recovery requirements not met: ${eligibility.missingRequirements.join(", ")}`,
};
}
const record = this.quarantineRecords.get(agentId)!;
const quarantineLevel = this.quarantineLevels.get(record.level)!;
// Determine new level based on performance
let newLevel: QuarantineLevel["level"] | "full_recovery";
const conditions: string[] = [];
if (
record.recoveryProgress.behaviorScore >= 0.9 &&
record.violations.length === 0
) {
newLevel = "full_recovery";
} else if (record.level === "complete") {
newLevel = "hard";
conditions.push("Continued monitoring for 30 days");
} else if (record.level === "hard") {
newLevel = "soft";
conditions.push("Continued monitoring for 14 days");
} else if (record.level === "soft") {
newLevel = "observation";
conditions.push("Continued monitoring for 7 days");
} else {
newLevel = "full_recovery";
}
// Update record
if (newLevel === "full_recovery") {
record.status = "recovered";
record.endTime = new Date();
this.quarantineRecords.delete(agentId);
this.recoveryPlans.delete(agentId);
} else {
record.level = newLevel;
record.metadata.notes.push(`Recovered to level: ${newLevel}`);
record.metadata.lastUpdated = new Date();
}
this.logger.info("Recovery request processed", {
agentId,
approved: true,
newLevel,
previousLevel: record.level,
conditions: conditions.length,
});
this.emit("recovery_processed", {
agentId,
approved: true,
newLevel,
record,
conditions,
});
return {
approved: true,
newLevel,
reason: "All recovery requirements met",
conditions: conditions.length > 0 ? conditions : undefined,
};
}
/**
* Record quarantine violation
*/
async recordViolation(
agentId: string,
type: QuarantineViolation["type"],
description: string,
evidence: any,
severity: QuarantineViolation["severity"] = "moderate",
): Promise<void> {
const record = this.quarantineRecords.get(agentId);
if (!record) return;
const violation: QuarantineViolation = {
violationId: crypto.randomUUID(),
type,
description,
timestamp: new Date(),
evidence,
severity,
penalty: this.calculateViolationPenalty(
severity,
record.violations.length,
),
};
record.violations.push(violation);
record.metadata.lastUpdated = new Date();
record.metadata.notes.push(`Violation: ${description}`);
// Apply penalties
if (violation.penalty.timeExtension) {
await this.extendQuarantine(
agentId,
violation.penalty.timeExtension,
`Violation penalty: ${description}`,
evidence,
);
}
if (violation.penalty.levelEscalation) {
await this.escalateQuarantine(
agentId,
this.getNextQuarantineLevel(record.level),
`Escalated due to violation: ${description}`,
evidence,
);
}
// Check for permanent ban
if (record.violations.length >= this.config.quarantine.permanentThreshold) {
record.status = "permanent";
record.metadata.notes.push(
"Permanently banned due to excessive violations",
);
}
this.logger.warn("Quarantine violation recorded", {
agentId,
type,
severity,
violationCount: record.violations.length,
penalty: violation.penalty,
});
this.emit("quarantine_violation", {
agentId,
violation,
record,
});
}
/**
* Helper methods
*/
private generateRecoveryPhases(
quarantineLevel: QuarantineLevel,
): RecoveryPhase[] {
const phases: RecoveryPhase[] = [];
// Phase 1: Compliance Assessment
phases.push({
phaseId: crypto.randomUUID(),
name: "Compliance Assessment",
description:
"Demonstrate understanding of security policies and protocols",
order: 1,
duration: 86400000, // 24 hours
challenges: [],
requirements: {
minChallengeScore: 0.7,
requiredEndorsements: 0,
behaviorThreshold: 0.6,
noViolations: true,
},
status: "pending",
});
// Phase 2: Behavioral Demonstration
if (quarantineLevel.recoveryRequirements.challengesRequired > 1) {
phases.push({
phaseId: crypto.randomUUID(),
name: "Behavioral Demonstration",
description:
"Demonstrate positive behavioral patterns and peer cooperation",
order: 2,
duration: 172800000, // 48 hours
challenges: [],
requirements: {
minChallengeScore: 0.8,
requiredEndorsements: Math.floor(
quarantineLevel.recoveryRequirements.peerEndorsements / 2,
),
behaviorThreshold: 0.7,
noViolations: true,
},
status: "pending",
});
}
// Phase 3: Trust Rebuilding
if (quarantineLevel.recoveryRequirements.challengesRequired > 3) {
phases.push({
phaseId: crypto.randomUUID(),
name: "Trust Rebuilding",
description:
"Rebuild trust through consistent positive behavior and peer endorsements",
order: 3,
duration: 259200000, // 72 hours
challenges: [],
requirements: {
minChallengeScore: 0.85,
requiredEndorsements:
quarantineLevel.recoveryRequirements.peerEndorsements,
behaviorThreshold: quarantineLevel.recoveryRequirements.behaviorScore,
noViolations: true,
},
status: "pending",
});
}
return phases;
}
private async generatePhaseChallenges(
agentId: string,
phase: RecoveryPhase,
quarantineLevel: QuarantineLevel,
): Promise<RecoveryChallenge[]> {
const challenges: RecoveryChallenge[] = [];
switch (phase.name) {
case "Compliance Assessment":
challenges.push({
challengeId: crypto.randomUUID(),
agentId,
type: "security_audit",
name: "Security Policy Quiz",
description:
"Complete a comprehensive quiz on security policies and protocols",
requirements: { questionsCount: 20, passingScore: 0.8 },
timeLimit: 3600000, // 1 hour
maxAttempts: 2,
passingScore: 0.8,
weight: 1.0,
status: "pending",
attempts: [],
});
break;
case "Behavioral Demonstration":
challenges.push({
challengeId: crypto.randomUUID(),
agentId,
type: "peer_collaboration",
name: "Peer Collaboration Task",
description:
"Successfully collaborate with other agents on a assigned task",
requirements: { collaborators: 3, taskComplexity: "medium" },
timeLimit: 7200000, // 2 hours
maxAttempts: 2,
passingScore: 0.75,
weight: 0.6,
status: "pending",
attempts: [],
});
if (quarantineLevel.recoveryRequirements.proofOfWork) {
challenges.push({
challengeId: crypto.randomUUID(),
agentId,
type: "proof_of_work",
name: "Computational Proof of Work",
description:
"Complete a computational challenge to demonstrate commitment",
requirements: { difficulty: 4, algorithm: "sha256" },
timeLimit: 3600000, // 1 hour
maxAttempts: 3,
passingScore: 1.0,
weight: 0.4,
status: "pending",
attempts: [],
});
}
break;
case "Trust Rebuilding":
challenges.push({
challengeId: crypto.randomUUID(),
agentId,
type: "behavioral_compliance",
name: "Extended Behavioral Compliance",
description:
"Maintain consistent positive behavior over extended period",
requirements: { duration: 172800000, minScore: 0.9 }, // 48 hours
timeLimit: 259200000, // 72 hours
maxAttempts: 1,
passingScore: 0.9,
weight: 1.0,
status: "pending",
attempts: [],
});
break;
}
return challenges;
}
private calculateRecoveryDuration(quarantineLevel: QuarantineLevel): number {
const baseDuration = quarantineLevel.duration.minimum;
const challengeTime =
quarantineLevel.recoveryRequirements.challengesRequired * 3600000; // 1 hour per challenge
const endorsementTime =
quarantineLevel.recoveryRequirements.peerEndorsements * 1800000; // 30 min per endorsement
return Math.max(baseDuration, challengeTime + endorsementTime);
}
private async signEndorsement(
fromAgentId: string,
toAgentId: string,
type: string,
strength: string,
): Promise<string> {
const data = `${fromAgentId}:${toAgentId}:${type}:${strength}:${Date.now()}`;
return crypto.createHash("sha256").update(data).digest("hex");
}
private async calculateEndorsementWeight(
endorserAgentId: string,
): Promise<number> {
// In a real implementation, this would calculate based on endorser's reputation
return 1.0; // Default weight
}
private calculateViolationPenalty(
severity: QuarantineViolation["severity"],
violationCount: number,
): QuarantineViolation["penalty"] {
const basePenalties = {
minor: { timeExtension: 3600000 }, // 1 hour
moderate: { timeExtension: 7200000 }, // 2 hours
severe: { timeExtension: 86400000, levelEscalation: violationCount >= 2 }, // 24 hours
critical: { timeExtension: 172800000, levelEscalation: true }, // 48 hours
};
const penalty = basePenalties[severity];
// Increase penalties for repeat offenders
if (violationCount > 3) {
penalty.timeExtension *= 2;
}
return penalty;
}
private getNextQuarantineLevel(
currentLevel: QuarantineLevel["level"],
): QuarantineLevel["level"] {
const escalation = {
observation: "soft",
soft: "hard",
hard: "complete",
complete: "complete", // Can't escalate further
};
return escalation[currentLevel] as QuarantineLevel["level"];
}
private calculateRecoveryProgress(
record: QuarantineRecord,
requirements: QuarantineLevel["recoveryRequirements"],
): number {
const weights = {
challenges: 0.4,
endorsements: 0.3,
behavior: 0.2,
stake: 0.1,
};
const challengeProgress = Math.min(
1,
record.recoveryProgress.challengesCompleted /
requirements.challengesRequired,
);
const endorsementProgress = Math.min(
1,
record.recoveryProgress.peerEndorsements / requirements.peerEndorsements,
);
const behaviorProgress = Math.min(
1,
record.recoveryProgress.behaviorScore / requirements.behaviorScore,
);
const stakeProgress =
requirements.economicStake > 0
? Math.min(
1,
record.recoveryProgress.stakePledged / requirements.economicStake,
)
: 1;
return (
challengeProgress * weights.challenges +
endorsementProgress * weights.endorsements +
behaviorProgress * weights.behavior +
stakeProgress * weights.stake
);
}
private async checkPhaseCompletion(agentId: string): Promise<void> {
const plan = this.recoveryPlans.get(agentId);
if (!plan) return;
const currentPhase = plan.phases[plan.progress.currentPhase];
if (!currentPhase || currentPhase.status !== "active") return;
// Check if all phase challenges are completed
const phaseChallenges = currentPhase.challenges
.map((id) => this.recoveryChallenges.get(id))
.filter(Boolean);
const completedChallenges = phaseChallenges.filter(
(c) => c!.status === "completed",
);
if (completedChallenges.length === phaseChallenges.length) {
// Phase completed
currentPhase.status = "completed";
currentPhase.completedAt = new Date();
plan.progress.phasesCompleted++;
// Move to next phase
if (plan.progress.currentPhase < plan.phases.length - 1) {
plan.progress.currentPhase++;
plan.phases[plan.progress.currentPhase].status = "active";
plan.phases[plan.progress.currentPhase].startedAt = new Date();
} else {
// All phases completed
plan.status = "completed";
}
// Update overall progress
plan.progress.overallProgress =
plan.progress.phasesCompleted / plan.phases.length;
plan.lastUpdated = new Date();
this.emit("phase_completed", {
agentId,
phase: currentPhase,
plan,
});
}
}
private async monitorQuarantinedAgents(): Promise<void> {
for (const [agentId, record] of this.quarantineRecords) {
if (record.status !== "active") continue;
try {
// Monitor behavior and compliance
const behaviorMetrics =
await this.behaviorMonitor.assessBehavior(agentId);
// Update monitoring data
record.monitoring.activityLevel = behaviorMetrics.activityLevel;
record.monitoring.complianceScore = behaviorMetrics.complianceScore;
record.monitoring.lastActivity = behaviorMetrics.lastActivity;
// Update behavior score
record.recoveryProgress.behaviorScore = behaviorMetrics.overallScore;
// Check for violations
if (behaviorMetrics.violations.length > 0) {
for (const violation of behaviorMetrics.violations) {
await this.recordViolation(
agentId,
violation.type,
violation.description,
violation.evidence,
violation.severity,
);
}
}
} catch (error) {
this.logger.error("Failed to monitor quarantined agent", {
agentId,
error,
});
}
}
}
private async reviewQuarantineStatus(): Promise<void> {
for (const [agentId, record] of this.quarantineRecords) {
if (record.status !== "active") continue;
const timeInQuarantine = Date.now() - record.startTime.getTime();
const quarantineLevel = this.quarantineLevels.get(record.level)!;
// Check if minimum time has passed
if (timeInQuarantine >= quarantineLevel.duration.minimum) {
const eligibility = await this.checkRecoveryEligibility(agentId);
if (eligibility.eligible) {
// Automatic recovery for observation level
if (
record.level === "observation" &&
record.violations.length === 0
) {
await this.processRecoveryRequest(agentId);
}
}
}
// Check maximum time limit
if (timeInQuarantine >= quarantineLevel.duration.maximum) {
if (
quarantineLevel.extendable &&
record.extensions.length < this.config.quarantine.maxExtensions
) {
// Auto-extend if recovery progress is being made
const eligibility = await this.checkRecoveryEligibility(agentId);
if (eligibility.progress > 0.5) {
await this.extendQuarantine(
agentId,
quarantineLevel.duration.minimum / 2,
"Automatic extension due to progress",
{},
);
}
} else {
// Force review or escalate
record.status = "permanent";
record.metadata.notes.push("Maximum quarantine time exceeded");
}
}
}
}
private async processRecoveryChallenges(): Promise<void> {
for (const [challengeId, challenge] of this.recoveryChallenges) {
if (challenge.status === "in_progress") {
// Check for timeouts
const lastAttempt = challenge.attempts[challenge.attempts.length - 1];
if (lastAttempt && !lastAttempt.endTime) {
const timeInProgress = Date.now() - lastAttempt.startTime.getTime();
if (timeInProgress > challenge.timeLimit) {
// Timeout
lastAttempt.endTime = new Date();
lastAttempt.feedback = "Challenge timed out";
challenge.status = "pending";
}
}
}
}
}
private scheduleQuarantineReview(agentId: string, delay: number): void {
setTimeout(async () => {
const record = this.quarantineRecords.get(agentId);
if (record && record.status === "active") {
await this.reviewQuarantineStatus();
}
}, delay);
}
private async escalateQuarantine(
agentId: string,
newLevel: QuarantineLevel["level"],
reason: string,
evidence: any,
): Promise<QuarantineRecord> {
const record = this.quarantineRecords.get(agentId);
if (!record) throw new Error("Agent not quarantined");
const extension: QuarantineExtension = {
extensionId: crypto.randomUUID(),
reason: `Escalated to ${newLevel}: ${reason}`,
additionalTime: 0, // Escalation changes level, not time
requestedBy: "system",
approvedBy: ["system"],
timestamp: new Date(),
evidence,
};
record.level = newLevel;
record.extensions.push(extension);
record.metadata.notes.push(`Escalated to ${newLevel}: ${reason}`);
record.metadata.lastUpdated = new Date();
this.logger.warn("Quarantine escalated", {
agentId,
oldLevel: record.level,
newLevel,
reason,
});
this.emit("quarantine_escalated", {
agentId,
record,
extension,
});
return record;
}
private async extendQuarantine(
agentId: string,
additionalTime: number,
reason: string,
evidence: any,
): Promise<void> {
const record = this.quarantineRecords.get(agentId);
if (!record) return;
const extension: QuarantineExtension = {
extensionId: crypto.randomUUID(),
reason,
additionalTime,
requestedBy: "system",
approvedBy: ["system"],
timestamp: new Date(),
evidence,
};
record.extensions.push(extension);
record.metadata.notes.push(`Extended by ${additionalTime}ms: ${reason}`);
record.metadata.lastUpdated = new Date();
this.emit("quarantine_extended", {
agentId,
record,
extension,
});
}
/**
* Public API methods
*/
getQuarantineRecord(agentId: string): QuarantineRecord | null {
return this.quarantineRecords.get(agentId) || null;
}
getRecoveryPlan(agentId: string): RecoveryPlan | null {
return this.recoveryPlans.get(agentId) || null;
}
getQuarantinedAgents(): string[] {
return Array.from(this.quarantineRecords.keys());
}
getRecoveryChallenges(agentId: string): RecoveryChallenge[] {
return Array.from(this.recoveryChallenges.values()).filter(
(c) => c.agentId === agentId,
);
}
getPeerEndorsements(agentId: string): PeerEndorsement[] {
return this.peerEndorsements.get(agentId) || [];
}
async getSystemStats(): Promise<any> {
const records = Array.from(this.quarantineRecords.values());
const challenges = Array.from(this.recoveryChallenges.values());
return {
totalQuarantined: records.length,
quarantineLevelDistribution: this.getQuarantineLevelDistribution(records),
totalChallenges: challenges.length,
challengeCompletionRate:
this.calculateChallengeCompletionRate(challenges),
averageRecoveryTime: this.calculateAverageRecoveryTime(records),
violationCount: records.reduce((sum, r) => sum + r.violations.length, 0),
recoverySuccessRate: this.calculateRecoverySuccessRate(records),
};
}
private getQuarantineLevelDistribution(
records: QuarantineRecord[],
): Record<string, number> {
const distribution = { observation: 0, soft: 0, hard: 0, complete: 0 };
records.forEach((record) => {
distribution[record.level]++;
});
return distribution;
}
private calculateChallengeCompletionRate(
challenges: RecoveryChallenge[],
): number {
if (challenges.length === 0) return 0;
const completed = challenges.filter((c) => c.status === "completed").length;
return completed / challenges.length;
}
private calculateAverageRecoveryTime(records: QuarantineRecord[]): number {
const recovered = records.filter(
(r) => r.status === "recovered" && r.endTime,
);
if (recovered.length === 0) return 0;
const totalTime = recovered.reduce((sum, r) => {
return sum + (r.endTime!.getTime() - r.startTime.getTime());
}, 0);
return totalTime / recovered.length;
}
private calculateRecoverySuccessRate(records: QuarantineRecord[]): number {
const total = records.filter((r) => r.status !== "active").length;
if (total === 0) return 0;
const recovered = records.filter((r) => r.status === "recovered").length;
return recovered / total;
}
}
// Supporting monitoring classes
class BehaviorMonitor {
constructor(private config: any) {}
async assessBehavior(agentId: string): Promise<{
activityLevel: number;
complianceScore: number;
overallScore: number;
lastActivity: Date;
violations: any[];
}> {
// Mock implementation
return {
activityLevel: 0.5,
complianceScore: 0.8,
overallScore: 0.7,
lastActivity: new Date(),
violations: [],
};
}
}
class RecoveryAssessor {
constructor(private config: any) {}
async assessRecoveryProgress(
agentId: string,
plan: RecoveryPlan,
): Promise<number> {
return plan.progress.overallProgress;
}
}
class ChallengeValidator {
constructor(private config: any) {}
async validateResponse(
challenge: RecoveryChallenge,
response: any,
): Promise<{
score: number;
feedback: string;
evidence: any;
}> {
// Mock validation
return {
score: 0.8,
feedback: "Good response",
evidence: { validated: true },
};
}
}
class EndorsementValidator {
constructor(private config: any) {}
async validateEndorser(
fromAgentId: string,
toAgentId: string,
): Promise<boolean> {
// Mock validation
return true;
}
}
export {
QuarantineRecoveryManager,
QuarantineLevel,
QuarantineRecord,
RecoveryChallenge,
PeerEndorsement,
RecoveryPlan,
QuarantineViolation,
};