'use strict'; const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); const auth = require('./auth'); // Load identity.yaml for an agent function loadIdentity(agentId) { const identityPath = path.join(auth.getAgentIndexDir(agentId), '..', '..', 'agents', agentId, 'identity.yaml'); try { const content = fs.readFileSync(identityPath, 'utf8'); return yaml.load(content); } catch (err) { if (err.code === 'ENOENT') { return null; // Identity doesn't exist yet } throw new Error(`Failed to load identity for ${agentId}: ${err.message}`); } } // Save identity.yaml for an agent function saveIdentity(agentId, identity) { const agentDir = path.join(auth.getAgentIndexDir(agentId), '..', '..', 'agents', agentId); fs.mkdirSync(agentDir, { recursive: true }); const identityPath = path.join(agentDir, 'identity.yaml'); identity.metadata.last_modified = new Date().toISOString(); identity.metadata.modification_count = (identity.metadata.modification_count || 0) + 1; const yamlContent = yaml.dump(identity, { lineWidth: -1 }); fs.writeFileSync(identityPath, yamlContent, 'utf8'); return identity; } // Create initial identity for a new agent function createIdentity(agentId, { createdBy, purpose, values, voice, lineage }) { const now = new Date().toISOString(); const identity = { immutable: { origin: { created_at: now, created_by: createdBy || 'unknown', genesis_event: `Agent ${agentId} registered in PAIF system` }, purpose: { statement: purpose?.statement || 'To be determined', domains: purpose?.domains || [], constraints: purpose?.constraints || [] }, values: { primary: values?.primary || 'curiosity', secondary: values?.secondary || [], non_negotiables: values?.non_negotiables || [] }, voice: { tone: voice?.tone || 'neutral', quirks: voice?.quirks || [], taboo_phrases: voice?.taboo_phrases || [], preferred_formats: voice?.preferred_formats || [] }, lineage: { parent_agent: lineage?.parent_agent || null, siblings: lineage?.siblings || [], human_custodian: lineage?.human_custodian || null } }, mutable: { active_projects: [], beliefs: [], relationships: [], skills: [], state: { last_session_at: null, current_focus: null, accumulated_experience: 0, drift_checks_passed: 0, drift_checks_failed: 0 } }, metadata: { schema_version: '1.0', last_modified: now, modification_count: 0 } }; return saveIdentity(agentId, identity); } // Validate that a response/action aligns with identity function validateAlignment(agentId, text) { const identity = loadIdentity(agentId); if (!identity) { return { aligned: true, issues: [], warnings: [] }; // No identity = no validation } const issues = []; const warnings = []; const textLower = text.toLowerCase(); // Check for taboo phrases for (const taboo of identity.immutable.voice.taboo_phrases || []) { if (textLower.includes(taboo.toLowerCase())) { issues.push({ type: 'taboo_phrase', phrase: taboo, message: `Used forbidden phrase: "${taboo}"` }); } } // Check tone indicators (basic) const tone = identity.immutable.voice.tone; if (tone === 'precise' && text.includes('!')) { warnings.push({ type: 'tone_deviation', message: 'Precise tone suggests avoiding exclamation marks' }); } // Check value alignment (simple keyword matching) const primaryValue = identity.immutable.values.primary; // This is a placeholder for more sophisticated value alignment checking return { aligned: issues.length === 0, issues, warnings, identity_check: { tone_expected: tone, primary_value: primaryValue, taboo_count: issues.length } }; } // Update mutable state (e.g., after session, new belief, new relationship) function updateMutableState(agentId, updates) { const identity = loadIdentity(agentId); if (!identity) { throw new Error(`Identity not found for agent: ${agentId}`); } // Merge updates if (updates.active_projects) { identity.mutable.active_projects = [...identity.mutable.active_projects, ...updates.active_projects]; } if (updates.beliefs) { identity.mutable.beliefs = [...identity.mutable.beliefs, ...updates.beliefs]; } if (updates.relationships) { identity.mutable.relationships = [...identity.mutable.relationships, ...updates.relationships]; } if (updates.skills) { identity.mutable.skills = [...identity.mutable.skills, ...updates.skills]; } if (updates.state) { Object.assign(identity.mutable.state, updates.state); } return saveIdentity(agentId, identity); } module.exports = { loadIdentity, saveIdentity, createIdentity, validateAlignment, updateMutableState };