/** * Interactive Architecture Diagram Component * Tractatus Framework - Phase 3: Interactive Architecture Diagram * * Handles click/hover interactions on the hexagonal service diagram * Shows service details in a side panel */ class InteractiveDiagram { constructor() { this.serviceData = { boundary: { name: 'BoundaryEnforcer', shortName: 'Boundary', color: '#10b981', icon: '🔒', description: 'Blocks AI from making values decisions (privacy, ethics, strategic direction). Requires human approval.', details: [ 'Enforces Tractatus 12.1-12.7 boundaries', 'Values decisions architecturally require humans', 'Prevents AI autonomous decision-making on ethical questions', 'External enforcement - harder to bypass via prompting' ], promise: 'Values boundaries enforced externally—harder to manipulate through prompting.' }, instruction: { name: 'InstructionPersistenceClassifier', shortName: 'Instruction', color: '#6366f1', icon: '📋', description: 'Stores instructions externally with persistence levels (HIGH/MEDIUM/LOW). Aims to reduce directive fade.', details: [ 'Quadrant-based classification (STR/OPS/TAC/SYS/STO)', 'Time-persistence metadata tagging', 'Temporal horizon modeling (STRATEGIC, OPERATIONAL, TACTICAL)', 'External storage independent of AI runtime' ], promise: 'Instructions stored outside AI—more resistant to context manipulation.' }, validator: { name: 'CrossReferenceValidator', shortName: 'Validator', color: '#8b5cf6', icon: '✓', description: 'Validates AI actions against instruction history. Aims to prevent pattern bias overriding explicit directives.', details: [ 'Cross-references AI claims with external instruction history', 'Detects pattern-based overrides of explicit user directives', 'Independent verification layer', 'Helps prevent instruction drift' ], promise: 'Independent verification—AI claims checked against external source.' }, pressure: { name: 'ContextPressureMonitor', shortName: 'Pressure', color: '#f59e0b', icon: '⚡', description: 'Monitors AI performance degradation. Escalates when context pressure threatens quality.', details: [ 'Tracks token usage, complexity, error rates', 'Detects degraded operating conditions', 'Adjusts verification requirements under pressure', 'Objective metrics for quality monitoring' ], promise: 'Objective metrics may detect manipulation attempts early.' }, metacognitive: { name: 'MetacognitiveVerifier', shortName: 'Metacognitive', color: '#ec4899', icon: '💡', description: 'Requires AI to pause and verify complex operations before execution. Structural safety check.', details: [ 'AI self-checks alignment, coherence, safety before execution', 'Structural pause-and-verify gates', 'Selective verification (not constant)', 'Architectural enforcement of reflection steps' ], promise: 'Architectural gates aim to enforce verification steps.' }, deliberation: { name: 'PluralisticDeliberationOrchestrator', shortName: 'Deliberation', color: '#14b8a6', icon: '👥', description: 'Facilitates multi-stakeholder deliberation for values conflicts where no single "correct" answer exists.', details: [ 'Non-hierarchical coordination for values conflicts', 'Stakeholder perspective representation', 'Consensus-building for ethical trade-offs', 'Addresses values pluralism in AI safety' ], promise: 'Facilitates deliberation across stakeholder perspectives for values conflicts.' } }; this.activeService = null; this.init(); } init() { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => this.setup()); } else { this.setup(); } console.log('[InteractiveDiagram] Initialized'); } setup() { const svg = document.getElementById('interactive-arch-diagram'); if (!svg) { console.warn('[InteractiveDiagram] SVG diagram not found'); return; } const nodes = svg.querySelectorAll('.service-node'); console.log(`[InteractiveDiagram] Found ${nodes.length} service nodes`); nodes.forEach(node => { const serviceId = node.getAttribute('data-service'); node.addEventListener('click', (e) => { e.preventDefault(); this.showServiceDetails(serviceId); }); node.addEventListener('mouseenter', () => { this.highlightService(serviceId); }); node.addEventListener('mouseleave', () => { this.unhighlightService(serviceId); }); }); this.addKeyboardNavigation(nodes); } highlightService(serviceId) { const svg = document.getElementById('interactive-arch-diagram'); if (!svg) return; const connectionLine = svg.querySelector(`#conn-${serviceId}`); if (connectionLine) { connectionLine.classList.add('active'); } const node = svg.querySelector(`#node-${serviceId}`); if (node) { node.classList.add('hover'); } } unhighlightService(serviceId) { const svg = document.getElementById('interactive-arch-diagram'); if (!svg) return; if (this.activeService === serviceId) return; const connectionLine = svg.querySelector(`#conn-${serviceId}`); if (connectionLine) { connectionLine.classList.remove('active'); } const node = svg.querySelector(`#node-${serviceId}`); if (node) { node.classList.remove('hover'); } } showServiceDetails(serviceId) { const service = this.serviceData[serviceId]; if (!service) { console.error('[InteractiveDiagram] Service not found:', serviceId); return; } this.activeService = serviceId; const svg = document.getElementById('interactive-arch-diagram'); if (svg) { svg.querySelectorAll('.service-node').forEach(n => n.classList.remove('active')); svg.querySelectorAll('.connection-line').forEach(l => l.classList.remove('active')); const node = svg.querySelector(`#node-${serviceId}`); if (node) { node.classList.add('active'); } const connectionLine = svg.querySelector(`#conn-${serviceId}`); if (connectionLine) { connectionLine.classList.add('active'); } } this.renderServicePanel(service); console.log('[InteractiveDiagram] Showing details for:', service.name); } renderServicePanel(service) { let panel = document.getElementById('service-detail-panel'); if (!panel) { panel = document.createElement('div'); panel.id = 'service-detail-panel'; panel.className = 'bg-white rounded-xl shadow-2xl p-6 border-2'; panel.style.borderColor = service.color; const container = document.querySelector('#diagram-container'); if (container) { container.appendChild(panel); } else { console.error('[InteractiveDiagram] Diagram container not found'); return; } } else { panel.style.borderColor = service.color; } const html = `
${service.description}