StackComponentProtocol — Cross-Cutting Concerns
Stack components are the stack’s equivalent of plugins. They extend what the stack can do by hooking into its lifecycle: memory saves, searches, loads, and periodic maintenance. Think of them as middleware for memory operations. When a memory is saved, every component gets notified. When search results come back, every component can re-rank them. When maintenance runs, every component does its background work.StackComponentProtocol Interface
Properties
Hook Dispatch
The stack calls component hooks at four points in its lifecycle:on_save
Called after a memory is saved. Can modify the memory by returning a modified version (returnNone to leave unchanged).
Used by:
- EmotionalTagging: Detects valence/arousal, adds emotional metadata
- MetaMemory: Initializes confidence tracking
- Embedding: Generates and stores vector representation
on_search
Called after search results are assembled. Returns the (possibly modified) results list. Components can re-rank, filter, or augment results. Used by:- Forgetting: Could filter out low-salience results
- EmotionalTagging: Could boost emotionally relevant results
on_load
Called duringload() working memory assembly. Components contribute to the context dict by mutating it directly.
Used by:
- Anxiety: Adds current anxiety levels and dimension scores
- Forgetting: Adds forgetting statistics
on_maintenance
Called during periodic maintenance. Each component does background work and returns a stats dict. The stack combines all stats keyed by component name. Used by:- Forgetting: Runs salience decay sweeps, soft-deletes low-salience memories
- Consolidation: Detects cross-domain patterns in episodes
- Suggestions: Scans raw entries for potential episodes/beliefs/notes
- MetaMemory: Applies confidence decay to stale memories
- Knowledge: Analyzes domain coverage and knowledge gaps
Error Isolation
Component failures never crash stack operations. If a component’s hook throws an exception, the stack logs the error and continues with the remaining components. This isolation means:- A buggy emotional tagger won’t prevent memory saves
- A failing embedding component won’t break search (results just won’t have embeddings)
- One component crashing during maintenance won’t prevent others from running
The 8 Default Components
SQLiteStack auto-loads all 8 built-in components on initialization. Passcomponents=[] for a bare stack, or an explicit list for custom configuration.
Component Configuration
Entry Point Registration
Stack components register in thekernle.stack_components entry point group:
Building a Custom Component
To create a custom stack component, implement theStackComponentProtocol: