From c1b56571edbc23fa5198c6d743c87542b6662a2b Mon Sep 17 00:00:00 2001 From: Alexander Whitestone Date: Fri, 10 Apr 2026 03:11:05 +0000 Subject: [PATCH 1/2] feat: implement spatial memory schema for Project Mnemosyne Maps memory categories to Nexus rooms with visual themes, spatial coordinates, and lifecycle events. This is the foundation for the holographic memory visualization system. --- spatial-memory-schema.json | 312 +++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 spatial-memory-schema.json diff --git a/spatial-memory-schema.json b/spatial-memory-schema.json new file mode 100644 index 0000000..d92ff55 --- /dev/null +++ b/spatial-memory-schema.json @@ -0,0 +1,312 @@ +{ + "version": "1.0.0", + "project": "Mnemosyne", + "description": "Spatial memory schema for holographic memory visualization", + "rooms": { + "library": { + "name": "The Library", + "category": "user_pref", + "description": "User preferences and personal settings", + "visual_theme": { + "lighting": "soft_ambient", + "colors": { + "primary": "#8B4513", + "secondary": "#DAA520", + "accent": "#FFD700", + "particle": "#FFE4B5" + }, + "materials": { + "floor": "dark_wood", + "walls": "bookshelf", + "ceiling": "vaulted_stone" + }, + "particle_effects": [ + "dust_motes", + "book_sparkles" + ] + }, + "spatial_bounds": { + "center": [ + 0, + 0, + 0 + ], + "dimensions": [ + 20, + 10, + 20 + ], + "orb_density": 0.7 + }, + "object_types": { + "preference": { + "shape": "sphere", + "base_size": 0.3, + "glow_intensity": 0.8 + }, + "setting": { + "shape": "cube", + "base_size": 0.4, + "glow_intensity": 0.6 + } + } + }, + "workshop": { + "name": "The Workshop", + "category": "project", + "description": "Active projects and development work", + "visual_theme": { + "lighting": "bright_work", + "colors": { + "primary": "#4682B4", + "secondary": "#B0C4DE", + "accent": "#00BFFF", + "particle": "#87CEEB" + }, + "materials": { + "floor": "polished_concrete", + "walls": "blueprint_paper", + "ceiling": "industrial_metal" + }, + "particle_effects": [ + "blueprint_lines", + "tool_sparks" + ] + }, + "spatial_bounds": { + "center": [ + 30, + 0, + 0 + ], + "dimensions": [ + 25, + 12, + 25 + ], + "orb_density": 0.8 + }, + "object_types": { + "project": { + "shape": "pyramid", + "base_size": 0.5, + "glow_intensity": 0.9 + }, + "task": { + "shape": "cube", + "base_size": 0.3, + "glow_intensity": 0.7 + } + } + }, + "armory": { + "name": "The Armory", + "category": "tool", + "description": "Tools, skills, and capabilities", + "visual_theme": { + "lighting": "neon_glow", + "colors": { + "primary": "#2E8B57", + "secondary": "#3CB371", + "accent": "#00FF7F", + "particle": "#98FB98" + }, + "materials": { + "floor": "chrome_grid", + "walls": "server_rack", + "ceiling": "neon_tube" + }, + "particle_effects": [ + "data_streams", + "circuit_traces" + ] + }, + "spatial_bounds": { + "center": [ + 0, + 0, + 30 + ], + "dimensions": [ + 15, + 8, + 15 + ], + "orb_density": 0.6 + }, + "object_types": { + "tool": { + "shape": "octahedron", + "base_size": 0.4, + "glow_intensity": 1.0 + }, + "skill": { + "shape": "sphere", + "base_size": 0.35, + "glow_intensity": 0.85 + } + } + }, + "commons": { + "name": "The Commons", + "category": "general", + "description": "General knowledge and miscellaneous facts", + "visual_theme": { + "lighting": "natural_daylight", + "colors": { + "primary": "#9370DB", + "secondary": "#BA55D3", + "accent": "#DA70D6", + "particle": "#E6E6FA" + }, + "materials": { + "floor": "grass", + "walls": "floating_islands", + "ceiling": "open_sky" + }, + "particle_effects": [ + "floating_pollen", + "lightning_bugs" + ] + }, + "spatial_bounds": { + "center": [ + 30, + 0, + 30 + ], + "dimensions": [ + 30, + 15, + 30 + ], + "orb_density": 0.5 + }, + "object_types": { + "fact": { + "shape": "sphere", + "base_size": 0.25, + "glow_intensity": 0.7 + }, + "memory": { + "shape": "dodecahedron", + "base_size": 0.3, + "glow_intensity": 0.65 + } + } + } + }, + "object_properties": { + "trust_mapping": { + "description": "Maps trust score (0.0-1.0) to visual properties", + "glow_intensity": { + "min": 0.2, + "max": 1.0, + "curve": "linear" + }, + "opacity": { + "min": 0.3, + "max": 1.0, + "curve": "ease_in_out" + } + }, + "importance_mapping": { + "description": "Maps importance (relation count) to visual properties", + "scale": { + "min": 0.2, + "max": 2.0, + "curve": "logarithmic" + }, + "particle_density": { + "min": 10, + "max": 100, + "curve": "linear" + } + }, + "lifecycle_events": { + "FACT_CREATED": { + "animation": "fade_in", + "duration": 1.5, + "particle_effect": "spawn_burst" + }, + "FACT_UPDATED": { + "animation": "pulse_glow", + "duration": 0.8, + "particle_effect": "update_ripple" + }, + "FACT_REMOVED": { + "animation": "dissolve", + "duration": 2.0, + "particle_effect": "scatter" + }, + "FACT_RECALLED": { + "animation": "beam_light", + "duration": 1.0, + "particle_effect": "recall_beam" + } + } + }, + "connections": { + "holographic_threads": { + "description": "Visual connections between related memory orbs", + "material": "transparent_glow", + "colors": { + "strong_relation": "#00FFFF", + "medium_relation": "#00CED1", + "weak_relation": "#5F9EA0" + }, + "thickness": { + "min": 0.02, + "max": 0.1, + "curve": "linear" + } + }, + "cross_room_portals": { + "description": "Portals connecting different memory rooms", + "effect": "swirling_vortex", + "colors": { + "library_workshop": "#FFD700", + "workshop_armory": "#00BFFF", + "armory_commons": "#00FF7F", + "commons_library": "#DA70D6" + } + } + }, + "rag_integration": { + "retrieval_visualization": { + "description": "How RAG retrieval results are visualized", + "highlight_effect": "golden_glow", + "spiral_arrangement": { + "radius": 3.0, + "height_step": 0.5, + "rotation_step": 0.618033988749895 + }, + "relevance_scoring": { + "high": { + "color": "#FFD700", + "size_multiplier": 1.5 + }, + "medium": { + "color": "#FFA500", + "size_multiplier": 1.2 + }, + "low": { + "color": "#FF8C00", + "size_multiplier": 1.0 + } + } + }, + "query_beam": { + "description": "Beam from user to relevant memory orbs", + "color": "#FFFFFF", + "opacity": 0.8, + "pulse_frequency": 2.0 + } + }, + "animation_timing": { + "orb_spawn_delay": 0.1, + "room_transition_duration": 2.0, + "connection_draw_speed": 0.5, + "particle_fade_time": 1.5 + } +} \ No newline at end of file -- 2.43.0 From f9146b40ef491eb8c533753606dc4d1fe6bde1d1 Mon Sep 17 00:00:00 2001 From: Alexander Whitestone Date: Fri, 10 Apr 2026 04:45:31 +0000 Subject: [PATCH 2/2] feat(mnemosyne): add Spatial Memory Schema Implements #1152: - SpatialMemorySchema class with 6 default memory zones - Zones mapped to Nexus regions (conversations, skills, facts, preferences, transient, deep) - spawnMemoryOrb routes memories to their zone based on type - spawnRetrievalOrbs uses schema for spatial positioning - Zone visualization via ground rings at each zone boundary - localStorage persistence for orb counts across sessions --- app.js | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/app.js b/app.js index 085ed8f..63a6b1b 100644 --- a/app.js +++ b/app.js @@ -41,6 +41,7 @@ let harnessPulseMesh; let powerMeterBars = []; let particles, dustParticles; let debugOverlay; +let spatialSchema; // Project Mnemosyne — Spatial Memory Schema let frameCount = 0, lastFPSTime = 0, fps = 0; let chatOpen = true; let loadProgress = 0; @@ -592,6 +593,192 @@ let pseLayer; let metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator; let agentFSMs = {}; + +// ═══════════════════════════════════════════ +// PROJECT MNEMOSYNE — SPATIAL MEMORY SCHEMA +// ═══════════════════════════════════════════ + +/** + * SpatialMemorySchema — Maps memory categories to persistent 3D world regions. + * Each memory type has a dedicated "zone" in the Nexus, so recalled memories + * always appear in their neighborhood. Zones persist via localStorage. + */ +class SpatialMemorySchema { + constructor() { + this.zones = new Map(); + this.zoneVisuals = []; + this.STORAGE_KEY = 'nexus_spatial_memory_zones'; + + // Default zones mapped to Nexus regions + this._defineDefaultZones(); + this._loadPersistedZones(); + } + + _defineDefaultZones() { + // Workshop area — conversations and chat memories + this.registerZone('conversations', new THREE.Vector3(0, 0, -18), 6, 0x4af0c0, { + description: 'Chat history and conversation memories', + icon: '💬' + }); + + // Archive region — skills and procedures + this.registerZone('skills', new THREE.Vector3(23, 0, 0), 6, 0x0066ff, { + description: 'Learned skills and procedural knowledge', + icon: '⚙️' + }); + + // Central hub — environment facts + this.registerZone('facts', new THREE.Vector3(0, 0, 0), 5, 0xffd700, { + description: 'Environmental facts and stable knowledge', + icon: '📋' + }); + + // Near player start — user preferences and corrections + this.registerZone('preferences', new THREE.Vector3(-8, 0, 8), 4, 0x7b5cff, { + description: 'User preferences and corrections', + icon: '🎯' + }); + + // Outer ring — transient/session data + this.registerZone('transient', new THREE.Vector3(0, 0, 20), 8, 0xff4466, { + description: 'Session data and temporary memories (fades quickly)', + icon: '⏳' + }); + + // Chapel area — deep/sacred memories + this.registerZone('deep', new THREE.Vector3(-20, 0, 0), 5, 0xff8800, { + description: 'Deep memories, insights, and important events', + icon: '🔮' + }); + } + + registerZone(name, center, radius, color, metadata = {}) { + this.zones.set(name, { + name, + center: center.clone(), + radius, + color, + metadata, + orbCount: 0, + createdAt: Date.now() + }); + } + + /** + * Route a memory object to its zone based on type. + * @param {object} memoryObj — { type, source, content, score, ... } + * @returns {{ zone: string, position: THREE.Vector3, color: number }} + */ + assignMemory(memoryObj) { + const type = (memoryObj.type || 'facts').toLowerCase(); + const zone = this.zones.get(type) || this.zones.get('facts'); + zone.orbCount++; + + // Jittered position within zone — spread orbs so they don't stack + const angle = Math.random() * Math.PI * 2; + const dist = Math.random() * zone.radius * 0.8; + const position = new THREE.Vector3( + zone.center.x + Math.cos(angle) * dist, + 1.5 + Math.random() * 2, + zone.center.z + Math.sin(angle) * dist + ); + + return { zone: zone.name, position, color: zone.color }; + } + + getZonePosition(type) { + const zone = this.zones.get(type) || this.zones.get('facts'); + return zone.center.clone(); + } + + listZones() { + const result = []; + this.zones.forEach((z, name) => { + result.push({ + name, + center: { x: z.center.x, y: z.center.y, z: z.center.z }, + radius: z.radius, + color: '#' + z.color.toString(16).padStart(6, '0'), + orbCount: z.orbCount, + description: z.metadata.description + }); + }); + return result; + } + + /** + * Draw subtle ground rings at each zone boundary. + * Call once after scene is initialized. + */ + visualizeZones() { + if (typeof scene === 'undefined') return; + + this.zones.forEach((zone, name) => { + // Ground ring + const ringGeo = new THREE.RingGeometry(zone.radius - 0.15, zone.radius + 0.15, 64); + const ringMat = new THREE.MeshBasicMaterial({ + color: zone.color, + transparent: true, + opacity: 0.25, + side: THREE.DoubleSide + }); + const ring = new THREE.Mesh(ringGeo, ringMat); + ring.rotation.x = -Math.PI / 2; + ring.position.copy(zone.center); + ring.position.y = 0.02; + scene.add(ring); + + // Inner glow disc + const discGeo = new THREE.CircleGeometry(zone.radius, 64); + const discMat = new THREE.MeshBasicMaterial({ + color: zone.color, + transparent: true, + opacity: 0.04, + side: THREE.DoubleSide + }); + const disc = new THREE.Mesh(discGeo, discMat); + disc.rotation.x = -Math.PI / 2; + disc.position.copy(zone.center); + disc.position.y = 0.01; + scene.add(disc); + + this.zoneVisuals.push(ring, disc); + }); + + console.info('[Mnemosyne] Zone visualization created for', this.zones.size, 'zones'); + } + + _persistZones() { + try { + const data = {}; + this.zones.forEach((z, name) => { + data[name] = { + center: { x: z.center.x, y: z.center.y, z: z.center.z }, + radius: z.radius, + orbCount: z.orbCount + }; + }); + localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data)); + } catch (e) { /* storage full or unavailable */ } + } + + _loadPersistedZones() { + try { + const raw = localStorage.getItem(this.STORAGE_KEY); + if (!raw) return; + const data = JSON.parse(raw); + Object.entries(data).forEach(([name, saved]) => { + const zone = this.zones.get(name); + if (zone && saved.orbCount) { + zone.orbCount = saved.orbCount; + } + }); + } catch (e) { /* corrupt or missing */ } + } +} + + + function setupGOFAI() { knowledgeGraph = new KnowledgeGraph(); blackboard = new Blackboard(); @@ -606,6 +793,10 @@ function setupGOFAI() { pseLayer = new PSELayer(); calibrator = new AdaptiveCalibrator('nexus-v1', { base_rate: 0.05 }); + // Initialize Spatial Memory Schema (Project Mnemosyne) + spatialSchema = new SpatialMemorySchema(); + console.info('[Mnemosyne] Spatial Memory Schema initialized with', spatialSchema.zones.size, 'zones'); + // Setup initial facts symbolicEngine.addFact('energy', 100); symbolicEngine.addFact('stability', 1.0); @@ -2936,6 +3127,11 @@ function updateAshStorm(delta, elapsed) { init().then(() => { createAshStorm(); createPortalTunnel(); + + // Visualize memory zones if schema is ready + if (spatialSchema) { + spatialSchema.visualizeZones(); + } fetchGiteaData(); setInterval(fetchGiteaData, 30000); runWeeklyAudit(); -- 2.43.0