System Architecture¶
Spector Memory is organized around a biological metaphor where each Java package corresponds to a brain region or cognitive mechanism. This isn't just naming β the architecture genuinely mirrors how biological memory systems interact.
Extensibility¶
| Component | Extension point | What you can customize |
|---|---|---|
SpectorMemory |
Single entry point for all operations | Configure tiers, capacities, embedding providers |
TierStore interface |
Add new memory tiers | Implement the interface + register in TierRouter β no other changes needed |
AbstractTierStore |
Common tier lifecycle | Extend for new off-heap tier stores with Arena/segment management |
RecallListener |
Post-recall hooks | Add async listeners for co-activation tracking, logging, metrics |
CognitiveIngestionTarget / RecallPipeline |
Discrete processing steps | Each step is independently testable and replaceable |
Data Flow: Ingestion¶
The ingestion pipeline is split across two layers:
IngestionPipeline(inspector-ingestion) β handles step 1 (embed) and chunking for large documentsCognitiveIngestionTarget(inspector-memory) β handles steps 2β9 (synaptic encoding β WAL)
sequenceDiagram
participant App as Application
participant SM as SpectorMemory
participant CT as CognitiveIngestionTarget
participant EP as EmbeddingProvider
participant SD as SurpriseDetector
participant FP as FlashbulbPolicy
participant SQ as ScalarQuantizer
participant TR as TierRouter
participant MI as MemoryIndex
participant WAL as MemoryWal
participant HG as HebbianGraph
participant TC as TemporalChain
participant EG as EntityGraph
App->>SM: remember(id, text, type, tags)
SM->>CT: ingestCognitive(id, text, vector, type, tags, ...)
Note over CT: Step 1: Embed (done by unified IngestionPipeline)
Note over CT: or via CognitiveIngestionTarget.ingestCognitive()
CT->>EP: embed(text)
EP-->>CT: float[4096]
Note over CT: Step 2: Encode tags
CT->>CT: SynapticTagEncoder.encode(tags) β 64-bit Bloom
Note over CT: Step 3: Surprise detection
CT->>SD: computeImportance(l2Norm)
SD-->>CT: importance (0.0 β 1.0)
Note over CT: Step 4: Flashbulb check
CT->>FP: evaluate(zScore)
FP-->>CT: flashbulb? β pin + max importance
Note over CT: Step 5: Quantize
CT->>SQ: encode(float[]) β byte[]
Note over CT: Step 6: Build header
CT->>CT: CognitiveHeader(timestamp, tags, importance, ...)
Note over CT: Step 7: Route & write
CT->>TR: write(type, header, quantized)
TR-->>CT: byte offset
Note over CT: Step 8: Index
CT->>MI: register(id, location, text, source, tags)
Note over CT: Step 9a: WAL
CT->>WAL: appendRemember(id, quantized)
Note over CT: Step 9b: Hebbian edge strengthening
CT->>HG: strengthen(currentIdx, previousIdx, 1.0f)
Note over CT: Step 9c: Temporal chain linking
CT->>TC: link(currentIdx, lastIdx, sessionId)
Note over CT: Step 9d: Entity extraction & graph population
CT->>EG: addEntity() + linkToMemory() + addRelation()
Note over CT: Step 10: Circadian check
CT->>CT: triggerReflectIfDue()
Note
When ingestion comes through the unified IngestionPipeline (e.g., file ingestion), embedding (step 1) is handled by the pipeline itself. CognitiveIngestionTarget.ingest() receives a pre-embedded vector and executes steps 2β9. When called via SpectorMemory.remember(), CognitiveIngestionTarget.ingestCognitive() handles embedding internally.
Note
Steps 9bβ9d are gracefully degrading: if any graph component is null (not configured) or throws, the step is skipped with a log.warn() and ingestion continues normally.
Data Flow: Recall¶
The recall pipeline executes parallel tier scans using Virtual Threads:
sequenceDiagram
participant App as Application
participant RP as RecallPipeline
participant EP as EmbeddingProvider
participant PS as ProspectiveScheduler
participant CT as ConcurrentTasks
participant CS as CognitiveScorer
participant SS as SuppressionSet
participant HP as HabituationPenalty
participant HG as HebbianGraph
participant TC as TemporalChain
participant EG as EntityGraph
App->>RP: recall("query", options)
Note over RP: Step 1: Embed query
RP->>EP: embed("query")
EP-->>RP: float[4096]
Note over RP: Step 2: Prospective reminders
RP->>PS: collectDue()
PS-->>RP: due reminders
Note over RP: Step 3: Parallel tier scanning
RP->>CT: forkJoinAll(scanTasks)
par Working Memory
CT->>CS: score(workingSegment, ...)
and Episodic Partition 1
CT->>CS: score(partition1, ...)
and Episodic Partition 2
CT->>CS: score(partition2, ...)
and Semantic
CT->>CS: score(semanticSlab, ...)
and Procedural
CT->>CS: score(proceduralSegment, ...)
end
CS-->>RP: List<ScoredRecord>
Note over RP: Step 4: Filter suppressed
RP->>SS: isSuppressed(id)?
Note over RP: Step 5a: Habituation penalty
RP->>HP: recordAndComputePenalty(id)
Note over RP: Step 5b: STDP causal boost
RP->>RP: CoActivationTracker.getPredictiveStrength()
Note over RP: Step 5c: Hebbian spreading activation
RP->>HG: activateNeighbors(seedIdx, depth=2)
HG-->>RP: graph-activated memory indices
Note over RP: Step 5d: Temporal chain extension
RP->>TC: followForward/Backward(idx, maxHops=3)
TC-->>RP: temporally-linked memory indices
Note over RP: Step 5e: Entity graph traversal
RP->>EG: extract query entities β BFS 2-hop
EG-->>RP: entity-linked memory indices
Note over RP: Step 6: Merge, dedup, sort β final top-K
RP-->>App: List<CognitiveResult>
Note over RP: Step 7: Async listeners (Virtual Thread)
RP->>RP: notify(HebbianListener, LtpListener)
Package Dependency Graph¶
graph LR
SM[SpectorMemory<br/>FaΓ§ade] --> CT[pipeline/<br/>CognitiveIngestionTarget]
SM --> RP[pipeline/<br/>RecallPipeline]
SM --> TR[cortex/<br/>TierRouter]
SM --> MI[index/<br/>MemoryIndex]
CT --> EP[embed-api/<br/>EmbeddingProvider]
CT --> SQ[core/<br/>ScalarQuantizer]
CT --> SD[dopamine/<br/>SurpriseDetector]
CT --> TR
CT --> MI
CT --> WAL[sync/<br/>MemoryWal]
CT --> HG[hebbian/<br/>HebbianGraph]
CT --> TC[temporal/<br/>TemporalChain]
CT --> EG[graph/<br/>EntityGraph]
CT --> EX[graph/<br/>EntityExtractor]
RP --> EP
RP --> CS[synapse/<br/>CognitiveScorer]
RP --> TR
RP --> MI
RP --> SS[inhibition/<br/>SuppressionSet]
RP --> HP[habituation/<br/>HabituationPenalty]
RP --> HG
RP --> TC
RP --> EG
CS --> SF[core/<br/>SimilarityFunction]
CS --> DS[synapse/<br/>DecayStrategy]
TR --> WM[cortex/<br/>WorkingMemoryStore]
TR --> EM[cortex/<br/>EpisodicMemoryStore]
TR --> SE[cortex/<br/>SemanticMemoryStore]
TR --> PR[cortex/<br/>ProceduralMemoryStore]
RP -.->|async| HL[pipeline/<br/>HebbianListener]
RP -.->|async| LL[pipeline/<br/>LtpListener]
style SM fill:#4a90d9,color:white
style CS fill:#e74c3c,color:white
style TR fill:#2ecc71,color:white
style HG fill:#e74c3c,color:white
style EG fill:#9b59b6,color:white
style TC fill:#f39c12,color:white
The 32-Byte Cognitive Record¶
Every memory is stored as a fixed-size binary record in off-heap memory:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 32-Byte Synaptic Header β
ββββββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββ¬βββββββββββββββ€
β timestamp β synaptic β exactNormβ import β centroidId β
β 8 bytes β tags β 4 bytes β ance β 4 bytes β
β (offset 0) β 8 bytes β (off 16) β 4 bytesβ (offset 24) β
β β (off 8) β β(off 20)β β
ββββββββββββββ΄βββββββββββ΄βββββββββββ΄βββββββββΌβββββββ¬ββββ¬ββββ€
β βrecallβvalβflgβ
β (continued) βcount βencβs β
β β2B β1B β1B β
β βoff 28βo30βo31β
βββββββββββββββββββββββββββββββββββββββββββββ΄βββββββ΄ββββ΄ββββ€
β Quantized Vector (N bytes) β
β INT8 values, 32-byte aligned β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Total record size = 32 (header) + N (quantized vector bytes), aligned to 32 bytes.
At 768 dimensions (INT8): 32 + 768 = 800 bytes/memory β 50,000 memories fit in 40 MB of off-heap RAM.
Next Steps¶
- 6-Phase Scoring Pipeline β the SIMD hot-loop that makes it fast
- 3-Layer Cognitive Graph β Hebbian, Entity, and Temporal graphs
- Cortex β Tier Stores β the 4-tier memory architecture
- Off-Heap Panama Design β zero-GC binary layout