ContextSnapshot
The core entity representing a preserved conversation context with multi-layer metadata.
Overview
ContextSnapshot is the fundamental entity in WakeIQX. It represents a single preserved context with metadata from all three temporal intelligence layers.
Location: src/domain/models/ContextSnapshot.ts
Purpose: Immutable record of conversational context with temporal intelligence metadata
Interface Definition
typescript
interface IContextSnapshot {
// Core properties
id: string; // UUID
project: string; // Project grouping
content: string; // Original content
summary: string; // AI-generated summary
tags: string; // AI-generated tags
source: string; // Provenance (mcp, api, manual)
timestamp: Date; // Creation time
metadata?: Record<string, unknown>;
// Layer 1: Causality (Past - WHY)
causality?: {
actionType: ActionType; // What action created this
causedBy: string | null; // Parent context ID
rationale: string; // Why this was created
dependencies: string[]; // Related context IDs
};
// Layer 2: Memory (Present - HOW)
memory?: {
tier: MemoryTier; // ACTIVE|RECENT|ARCHIVED|EXPIRED
lastAccessed: Date | null; // LRU timestamp
accessCount: number; // How many times accessed
};
// Layer 3: Propagation (Future - WHAT)
propagation?: {
predictionScore: number; // 0.0-1.0
lastPredicted: Date | null; // When prediction was updated
predictedNextAccess: Date | null; // Estimated next access
propagationReason: string[]; // Why score is high/low
};
}Properties
Core Properties
id
- Type:
string - Format: UUID v4
- Example:
"550e8400-e29b-41d4-a716-446655440000" - Purpose: Unique identifier for referencing
project
- Type:
string - Required: Yes
- Example:
"authentication-refactor" - Purpose: Group related contexts together
content
- Type:
string - Required: Yes
- Example: Raw conversation text, code, decisions
- Purpose: Original unprocessed content
summary
- Type:
string - Generated by: AI (llama-3.1-8b-instruct)
- Example:
"Decision to use OAuth2 with PKCE for mobile app authentication" - Purpose: Compressed semantic essence for quick scanning
tags
- Type:
string - Format: Comma-separated
- Generated by: AI
- Example:
"oauth, security, mobile, authentication, pkce" - Purpose: Searchable keywords
source
- Type:
string - Default:
"unknown" - Common values:
"mcp","api","manual","cli" - Purpose: Provenance tracking
timestamp
- Type:
Date - Format: ISO 8601
- Example:
"2025-10-17T15:30:00Z" - Purpose: Temporal ordering
metadata
- Type:
Record<string, unknown> - Optional: Yes
- Example:
{ userId: "user-123", sessionId: "session-xyz" } - Purpose: Extensible custom data
Layer 1: Causality Properties
causality.actionType
- Type:
ActionType - Values:
conversation | decision | file_edit | tool_use | research - Example:
"decision" - Purpose: Classify what created this context
causality.causedBy
- Type:
string | null - Example:
"parent-context-id"ornull(root cause) - Purpose: Link to parent in causal chain
causality.rationale
- Type:
string - Example:
"OAuth2 with PKCE is more secure than JWT for mobile" - Purpose: Explain why this was created
causality.dependencies
- Type:
string[] - Example:
["research-id-1", "research-id-2"] - Purpose: Track related contexts (not causal)
Layer 2: Memory Properties
memory.tier
- Type:
MemoryTier - Values:
ACTIVE | RECENT | ARCHIVED | EXPIRED - Calculated based on: Time since last access
- Purpose: Classify current relevance
memory.lastAccessed
- Type:
Date | null - Updated: Every time context is loaded
- Purpose: LRU tracking
memory.accessCount
- Type:
number - Default:
0 - Updated: Incremented on each access
- Purpose: Frequency tracking
Layer 3: Propagation Properties
propagation.predictionScore
- Type:
number - Range:
0.0to1.0 - Example:
0.851 - Purpose: Likelihood of future access
propagation.lastPredicted
- Type:
Date | null - Purpose: Track prediction staleness
propagation.predictedNextAccess
- Type:
Date | null - Purpose: Estimated next access time (future enhancement)
propagation.propagationReason
- Type:
string[] - Example:
["recently_accessed", "causal_chain_root", "decision_node"] - Purpose: Explain prediction score
Methods
isExpired(): boolean
Check if context is older than 30 days:
typescript
isExpired(): boolean {
const age = Date.now() - this.timestamp.getTime();
const thirtyDays = 30 * 24 * 60 * 60 * 1000;
return age > thirtyDays;
}Use case: Determine pruning candidates
isRootCause(): boolean
Check if this context is a root of a causal chain:
typescript
isRootCause(): boolean {
return this.causality?.causedBy === null;
}Use case: Identify starting points of decision chains
Creation
Via ContextService
typescript
const snapshot = await contextService.saveContext({
project: 'my-project',
content: 'Decision: Use PostgreSQL for better JSON support',
metadata: {
actionType: 'decision',
causedBy: 'research-context-id',
rationale: 'Need JSONB indexing capabilities'
}
});Direct Construction (Testing)
typescript
const snapshot: IContextSnapshot = {
id: crypto.randomUUID(),
project: 'test-project',
content: 'Test content',
summary: 'Test summary',
tags: 'test, example',
source: 'manual',
timestamp: new Date(),
causality: {
actionType: 'conversation',
causedBy: null,
rationale: 'Test case',
dependencies: []
},
memory: {
tier: MemoryTier.ACTIVE,
lastAccessed: new Date(),
accessCount: 0
},
propagation: {
predictionScore: 0.5,
lastPredicted: new Date(),
predictedNextAccess: null,
propagationReason: ['test']
}
};Immutability
Snapshots are immutable once created:
- Create new snapshot for updates (don't modify existing)
- ID never changes
- Timestamp never changes
- Content never changes
Mutable properties (updated in database):
memory.lastAccessed(updated on access)memory.accessCount(incremented on access)memory.tier(recalculated periodically)propagation.*(updated by prediction engine)
Database Mapping
ContextSnapshot maps to context_snapshots table:
sql
CREATE TABLE context_snapshots (
-- Core
id TEXT PRIMARY KEY,
project TEXT NOT NULL,
content TEXT, -- Not returned in queries (large)
summary TEXT NOT NULL,
tags TEXT,
source TEXT,
timestamp DATETIME,
-- Layer 1
action_type TEXT,
caused_by TEXT,
rationale TEXT,
dependencies TEXT, -- JSON array
-- Layer 2
memory_tier TEXT,
last_accessed TEXT,
access_count INTEGER,
-- Layer 3
prediction_score REAL,
last_predicted TEXT,
predicted_next_access TEXT,
propagation_reason TEXT -- JSON array
);Type Guards
Check if causality exists
typescript
function hasCausality(snapshot: IContextSnapshot): boolean {
return snapshot.causality !== undefined;
}Check if propagation exists
typescript
function hasPrediction(snapshot: IContextSnapshot): boolean {
return snapshot.propagation?.predictionScore !== undefined;
}Examples
Minimal Context
typescript
const minimal: IContextSnapshot = {
id: crypto.randomUUID(),
project: 'my-project',
content: 'User asks: How do I authenticate?',
summary: 'User question about authentication',
tags: 'authentication, question',
source: 'mcp',
timestamp: new Date()
};Full Context with All Layers
typescript
const full: IContextSnapshot = {
id: crypto.randomUUID(),
project: 'auth-refactor',
content: 'Decision: Use OAuth2 with PKCE for mobile app',
summary: 'Authentication architecture decision',
tags: 'oauth, security, mobile, architecture',
source: 'mcp',
timestamp: new Date(),
metadata: {
userId: 'user-123',
sessionId: 'session-xyz'
},
causality: {
actionType: 'decision',
causedBy: 'research-context-id',
rationale: 'PKCE prevents authorization code interception',
dependencies: ['research-1', 'research-2']
},
memory: {
tier: MemoryTier.ACTIVE,
lastAccessed: new Date(),
accessCount: 5
},
propagation: {
predictionScore: 0.851,
lastPredicted: new Date(),
predictedNextAccess: null,
propagationReason: [
'recently_accessed',
'causal_chain_root',
'decision_node'
]
}
};See Also
- API Overview - Service architecture
- CausalityService - Layer 1 API
- MemoryManagerService - Layer 2 API
- PropagationService - Layer 3 API
- Database Schema - Storage details
