Skip to content
NeuroCognitive Architecture Badge

Memory System Architecture Analysis & Refactoring Plan

Date: April 14, 2025
Author: Justin Lietz Document Version: 1.0

Executive Summary

This document presents a comprehensive analysis of the Neuroca memory system architecture, identifying redundancies, architectural misalignments, and other issues discovered during code refactoring. It outlines a detailed plan for resolving these issues while maintaining system functionality and adhering to AMOS (Apex Modular Organization Standard) guidelines.

The memory system is critical to the Neuroca platform, providing tiered memory storage (STM, MTM, LTM) with human-like forgetting and consolidation mechanisms. However, its evolution has led to multiple implementations of similar functionality, creating maintenance challenges and potential bugs.

We have already taken the first step by refactoring manager.py into a modular structure. This document outlines the next steps needed to create a cohesive, well-organized memory architecture.


Table of Contents

  1. Current Architecture Analysis
  2. Redundancy Assessment
  3. Completed Refactoring
  4. Recommended Improvements
  5. Implementation Plan
  6. Backwards Compatibility
  7. Risk Assessment

Current Architecture Analysis

High-Level Components

The current memory system architecture consists of the following main components:

  1. Tier-Specific Storage Implementations
  2. src/neuroca/memory/stm/storage.py: Short-Term Memory storage
  3. src/neuroca/memory/mtm/storage.py: Medium-Term Memory storage
  4. src/neuroca/memory/ltm/storage.py: Long-Term Memory storage

  5. Memory Type Implementations

  6. src/neuroca/memory/episodic_memory.py: Episodic memory system
  7. src/neuroca/memory/semantic_memory.py: Semantic memory system
  8. src/neuroca/memory/working_memory.py: Working memory system

  9. Storage Backends

  10. src/neuroca/memory/backends/redis_backend.py: Redis implementation
  11. src/neuroca/memory/backends/sql_backend.py: SQL implementation
  12. src/neuroca/memory/backends/vector_backend.py: Vector search implementation
  13. src/neuroca/memory/backends/factory.py: Factory for creating backends

  14. Memory Processes

  15. src/neuroca/memory/memory_consolidation.py: Memory consolidation functions
  16. src/neuroca/memory/memory_decay.py: Memory decay functions
  17. src/neuroca/memory/memory_retrieval.py: Memory retrieval functions

  18. Core Memory System

  19. src/neuroca/core/memory/consolidation.py: More complex consolidation logic
  20. src/neuroca/core/memory/episodic_memory.py: Core episodic memory implementation
  21. src/neuroca/core/memory/factory.py: Memory system factory
  22. src/neuroca/core/memory/health.py: Memory health monitoring
  23. src/neuroca/core/memory/interfaces.py: Memory system interfaces
  24. src/neuroca/core/memory/semantic_memory.py: Core semantic memory implementation
  25. src/neuroca/core/memory/working_memory.py: Core working memory implementation

  26. Manager (Newly Refactored)

  27. src/neuroca/memory/manager.py: Original monolithic manager (now a facade)
  28. src/neuroca/memory/manager/ directory: Decomposed modules

Component Interactions

The interactions between these components reveal several circular dependencies:

  1. Storage Backend Factory Dependencies:
  2. StorageBackendFactory in backends/factory.py imports from tier-specific storage modules (stm/storage.py, mtm/storage.py, ltm/storage.py)
  3. These tier-specific modules may also use backends such as Redis, SQL, etc.

  4. Memory Consolidation Flow:

  5. Multiple implementations of consolidation: simple functions in memory_consolidation.py, complex class in core/memory/consolidation.py, and our new implementation in manager/consolidation.py

  6. Manager Component:

  7. Previously monolithic implementation now refactored into multiple files
  8. Uses StorageBackendFactory to create storage backends
  9. Implements its own consolidation/decay logic while similar functionality exists elsewhere

Redundancy Assessment

Storage Implementation Redundancies

Module Function Redundant With Issue
ltm/storage.py LTM Storage sql_backend.py & vector_backend.py Contains implementations that could be moved to backends
mtm/storage.py MTM Storage redis_backend.py Contains Redis-like functionality with custom implementation
stm/storage.py STM Storage None (unique) Generally self-contained but should conform to common interfaces

Memory Process Redundancies

Process Implementations Issue
Consolidation memory_consolidation.py
core/memory/consolidation.py
manager/consolidation.py
Three separate implementations with overlapping functionality
Decay memory_decay.py
manager/decay.py
Two implementations of similar functionality
Memory Retrieval memory_retrieval.py
• Retrieval methods in storage classes
• Retrieval methods in manager
Multiple implementations of retrieval logic

Core vs. Regular Memory Implementations

The core/memory/ directory contains implementations that appear to duplicate functionality in the regular memory/ directory:

Core Implementation Regular Implementation Overlap
core/memory/episodic_memory.py memory/episodic_memory.py Episodic memory functionality
core/memory/semantic_memory.py memory/semantic_memory.py Semantic memory functionality
core/memory/working_memory.py memory/working_memory.py Working memory functionality

Code Inspection Findings

  1. StorageBackendFactory Analysis:
  2. Creates backends based on tier (STM, MTM, LTM)
  3. For each tier, uses a tier-specific storage class (STMStorage, MTMStorage, LTMStorage)
  4. These tier-specific classes have their own backend implementations
  5. Creates circular dependencies and confusion about which implementation to use

  6. Consolidation Logic Comparison:

  7. memory_consolidation.py: Simple functions for adding metadata to memories during consolidation
  8. core/memory/consolidation.py: Complex StandardMemoryConsolidator class with activation thresholds, emotional salience, etc.
  9. manager/consolidation.py: New implementation focused on automatic consolidation between tiers

  10. Decay Logic Comparison:

  11. memory_decay.py: Simple stub implementations for decay calculation
  12. manager/decay.py: More elaborate implementation with access count, importance weighting

Completed Refactoring

We have already completed the following refactoring:

  1. Decomposed src/neuroca/memory/manager.py (>1000 lines) into separate modules:
  2. manager/__init__.py: Package exports
  3. manager/models.py: RankedMemory data class
  4. manager/utils.py: Helper functions for formatting, relevance calculation
  5. manager/storage.py: Storage operations across tiers
  6. manager/consolidation.py: Memory consolidation between tiers
  7. manager/decay.py: Memory decay and strengthening
  8. manager/working_memory.py: Working memory buffer management
  9. manager/core.py: Main MemoryManager class orchestrating everything

  10. Created a facade in manager.py that re-exports the refactored components for backward compatibility

All files now comply with the AMOS 500-line limit while preserving functionality.


Target Architecture

Based on our analysis of the current system, we have identified the clear target architecture we want to achieve. This architecture features clean separation of concerns with proper abstraction layers:

  1. Storage Backends: Low-level database interfaces (Redis, SQL, Vector)
  2. Handles direct interaction with specific database technologies
  3. Provides basic CRUD operations optimized for each database type
  4. Completely independent of memory logic

  5. Memory Tiers: Logical tier-specific behaviors (STM, MTM, LTM)

  6. Implements tier-specific behaviors (e.g., TTL for STM, priority for MTM)
  7. Uses the storage backends for persistence
  8. Knows nothing about memory types or the manager

  9. Memory Manager: Central orchestration layer

  10. Coordinates operations across all tiers
  11. Implements cross-tier functionality (consolidation, decay)
  12. Provides a clean, unified public API
  13. Handles context-driven memory retrieval and working memory

  14. Memory Types: (Episodic, Semantic, Working)

  15. Specialized memory implementations
  16. Use the Memory Manager as their interface to the system

The goal is to create a cohesive, well-structured system without redundancy or circular dependencies, where each component has a clear responsibility and well-defined interfaces.


Implementation Plan

Instead of implementing incremental fixes, we will proceed directly to the target architecture. This ensures we avoid temporary solutions and maintain a clear path to our goal. The plan consists of five clear phases:

Phase 1: Detailed Architecture Design (1 week)

  1. Define Core Interfaces
  2. Task: Create interface definitions for all core components
  3. Output:
    • src/neuroca/memory/interfaces/storage_backend.py: Abstract interface for storage backends
    • src/neuroca/memory/interfaces/memory_tier.py: Abstract interface for memory tiers
    • src/neuroca/memory/interfaces/memory_manager.py: Public API for the memory system
  4. Details: Define all methods, parameters, return types, and expected behaviors

  5. Design Data Models

  6. Task: Design standardized data models for memory items
  7. Output: src/neuroca/memory/models/ directory with Pydantic models
  8. Details: Create models for memory items, metadata, search criteria, etc.

  9. Map Component Interactions

  10. Task: Create sequence diagrams for key operations
  11. Output: Detailed sequence diagrams for operations like add/retrieve/search
  12. Details: Document how components interact for each operation

  13. Define Directory Structure

  14. Task: Design the final directory structure
  15. Output: Directory layout documentation
  16. Details: Specify where each component will live in the final architecture

  17. Create Comprehensive Test Plan

  18. Task: Design test cases covering all functionality
  19. Output: Test specifications for each component
  20. Details: Include unit, integration, and system tests

Phase 2: Implementation of New Core Components (2 weeks)

  1. Implement Storage Backend Interfaces
  2. Task: Create backend implementations for Redis, SQL, Vector DB
  3. Output:
    • src/neuroca/memory/backends/redis_backend.py
    • src/neuroca/memory/backends/sql_backend.py
    • src/neuroca/memory/backends/vector_backend.py
  4. Approach: Test-driven development, implement one backend at a time

  5. Implement Memory Tier Interfaces

  6. Task: Create tier implementations for STM, MTM, LTM
  7. Output:
    • src/neuroca/memory/tiers/stm.py
    • src/neuroca/memory/tiers/mtm.py
    • src/neuroca/memory/tiers/ltm.py
  8. Approach: Implement tier-specific logic using the backend interfaces

  9. Implement Memory Manager

  10. Task: Create the new MemoryManager implementation
  11. Output: src/neuroca/memory/manager/manager.py
  12. Details: Implements memory management operations using the tier interfaces

  13. Create Unit Tests

  14. Task: Write comprehensive tests for all new components
  15. Output: tests/unit/memory/ directory with test files
  16. Details: Ensure high code coverage and test all edge cases

Phase 3: Migration of Existing Code (1 week)

  1. Identify All Usage Points
  2. Task: Find all places in the codebase that use memory systems
  3. Output: Comprehensive list of files to be updated
  4. Details: Include exact file locations and line numbers

  5. Create Migration Facade

  6. Task: Build a facade over the new architecture for backward compatibility
  7. Output: Updated src/neuroca/memory/manager.py
  8. Details: Ensures old code can use the new implementation seamlessly

  9. Update Client Code

  10. Task: Modify all client code to use the new memory manager
  11. Schedule: Update code in priority order (core→integration→API→tools)
  12. Approach: Systematic update of all identified usage points

  13. Integration Testing

  14. Task: Test the updated code with the new memory system
  15. Output: Integration test results
  16. Details: Ensure all functionality works as expected with the new implementation

Phase 4: Cleanup and Removal of Old Code (1 week)

  1. Verify No References to Old Code
  2. Task: Search for imports of deprecated modules
  3. Output: Confirmation that no code references the old implementations
  4. Details: Use code search to verify complete migration

  5. Remove Redundant Implementations

  6. Task: Delete all redundant code
  7. Files to Remove:
    • src/neuroca/memory/memory_consolidation.py
    • src/neuroca/memory/memory_decay.py
    • src/neuroca/memory/memory_retrieval.py
    • src/neuroca/core/memory/* (if fully superseded)
    • src/neuroca/memory/stm/storage.py (if fully implemented in new architecture)
    • src/neuroca/memory/mtm/storage.py (if fully implemented in new architecture)
    • src/neuroca/memory/ltm/storage.py (if fully implemented in new architecture)
  8. Approach: Remove files one by one, running tests after each removal

  9. Simplify Factory Implementation

  10. Task: Update StorageBackendFactory to use new architecture
  11. Output: Updated src/neuroca/memory/backends/factory.py
  12. Details: Eliminate circular dependencies

Phase 5: Documentation and Final Validation (1 week)

  1. Update Documentation
  2. Task: Create comprehensive documentation for the new architecture
  3. Output:
    • Updated src/neuroca/memory/README.md
    • Architecture documentation
    • API reference
  4. Details: Include examples, best practices, and migration guides

  5. Final System Testing

  6. Task: Run full test suite and perform manual testing
  7. Output: Test reports and validation results
  8. Details: Ensure all functionality works correctly and there are no regressions

  9. Performance Benchmarking

  10. Task: Compare performance of new vs. old implementations
  11. Output: Performance metrics
  12. Details: Ensure the new implementation meets or exceeds performance requirements

  13. Code Quality Review

  14. Task: Perform final code review
  15. Output: Code quality metrics
  16. Details: Ensure the code meets all quality standards and AMOS guidelines

Backwards Compatibility

To maintain backward compatibility throughout this refactoring:

  1. Facade Pattern:
  2. Keep original entry points (manager.py) as facades to new implementations
  3. Proxy calls to new implementations while maintaining original interfaces

  4. Adapter Classes:

  5. Create adapter classes that implement old interfaces but use new implementations
  6. Place these in appropriate locations for easy discovery

  7. Deprecation Warnings:

  8. Use standard Python deprecation warnings to alert developers
  9. Include specific migration paths in warnings
  10. Example:

    import warnings
    
    def consolidate_memory(memory_data, memory_type="episodic"):
        warnings.warn(
            "This function is deprecated. Use MemoryManager.consolidate_memory() instead.",
            DeprecationWarning,
            stacklevel=2
        )
        # Call new implementation or implement compatibility logic
    

  11. Version Support Policy:

  12. Define how long deprecated interfaces will be supported
  13. Communicate this policy clearly in documentation
  14. Example policy: "Deprecated interfaces will be supported for two minor versions before removal."

  15. Documentation:

  16. Provide clear migration guides for each deprecated component
  17. Include code examples showing old vs. new usage

Risk Assessment

Risk Impact Likelihood Mitigation
Breaking existing functionality High Medium Comprehensive test suite, gradual rollout, facade pattern
Circular dependencies Medium High Careful refactoring with dependency injection or import indirection
Performance degradation Medium Low Benchmark key operations before and after changes
Increased complexity during transition Medium High Detailed documentation, clear migration paths
Missed usage patterns High Medium Thorough code analysis, engagement with all teams

Key Risk Areas

  1. Integration with Cognitive Control System:
  2. src/neuroca/core/cognitive_control/ may directly use memory systems
  3. Need to ensure these interactions are preserved or properly migrated

  4. API & External Interfaces:

  5. src/neuroca/api/routes/memory.py exposes memory functionality
  6. Must maintain compatibility or provide clear migration path

  7. Event System Integration:

  8. src/neuroca/core/events/memory.py suggests event-based interactions
  9. Ensure event handling is preserved during refactoring

  10. Test Coverage Gaps:

  11. Need to ensure all functionality has adequate test coverage
  12. Missing tests could allow regressions during refactoring

Mitigation Strategies

  1. Incremental Approach:
  2. Refactor one component at a time
  3. Verify functionality after each change
  4. Roll back changes if issues are detected

  5. Feature Flags:

  6. Implement feature flags for new implementations
  7. Allow gradual rollout and easy rollback
  8. Example:

    if settings.use_new_memory_manager:
        # Use new implementation
    else:
        # Use old implementation
    

  9. Monitoring & Logging:

  10. Add detailed logging during transition
  11. Monitor for errors or unexpected behavior
  12. Set up alerts for potential issues

  13. Stakeholder Communication:

  14. Keep all teams informed of changes
  15. Provide clear timelines and expectations
  16. Solicit feedback throughout the process

This document will be updated as refactoring progresses and additional findings are discovered.