Episodic Memory
The Foundation of GESA's Learning
GESA operates exclusively on episodic memory — not semantic memory. This distinction is fundamental to how the system learns.
Semantic vs Episodic
| Memory Type | Definition | Example |
|---|---|---|
| Semantic | General facts, rules, knowledge | "High context switching causes burnout" |
| Episodic | Situated experience with context, action, outcome, and time | "On March 3rd, reducing meetings for Team A by 40% resolved a 3-day pain streak within 2 sprints" |
Semantic memory tells you what is generally true. Episodic memory tells you what happened here, to this entity, under these conditions, and what resulted.
GESA needs episodic memory because:
- The same intervention produces different outcomes in different contexts
- Timing, temperature, and conditions matter as much as the action itself
- General knowledge cannot capture the specifics that determine whether a strategy will work this time
The Episode Schema
Every GESA episode is an immutable record of a situated decision:
interface Episode {
id: string // Unique identifier
timestamp: DateTime // When this episode occurred
context: EpisodeContext // What was the situation?
action: EpisodeAction // What was done?
outcome: EpisodeOutcome // What happened?
driftBefore: number // Gap before action
driftAfter: number // Gap after action (populated post-outcome)
fetchScore: number // Decision confidence at time of action
temperature: number // Annealing temperature at time of action
tags: string[] // Searchable episode metadata
}Why Immutability Matters
Episodes must be immutable after capture. If episode metadata can be mutated after the fact, the entire retrieval and generation layer builds on unreliable ground.
This principle was discovered through a production bug in StratIQX where a structural proxy silently overrode semantic intent across multiple system boundaries. The fix — Object.freeze() + Proxy mutation detection — is the technical mechanism that makes semantic intent enforceable.
Immutable episodes are not a design preference. They are a correctness requirement.
Episode Context
The context fingerprint is what makes retrieval possible. It captures the conditions under which a decision was made:
interface EpisodeContext {
domain: string // Content, Workplace, Trading, Browser, Business, Product
dimension: string // D1–D6 in 6D context, or domain-specific
driftScore: number // Gap magnitude at time of decision
driftSign: 'positive' | 'negative' | 'zero'
fetchScore: number // Action confidence
chirp: number // Signal strength
perch: number // Structural confidence
wake: number // Temporal context
tags: string[] // Domain-specific contextual labels
}Two episodes with similar context fingerprints are similar situations — even if they occurred in different runs, different teams, or different time periods. The similarity function retrieves them together.
Episode Action
What was actually done:
interface EpisodeAction {
type: string // The class of intervention
description: string // Human-readable description
parameters: object // Domain-specific action parameters
source: 'gesa_recommended' | 'manual' | 'automatic'
confidence: number // Confidence at time of action
}Recording whether an action was GESA-recommended vs manual is important: it allows GESA to learn whether its own recommendations outperform alternatives over time.
Episode Outcome
What happened as a result:
interface EpisodeOutcome {
driftAfter: number // Gap after action
gapChange: number // driftBefore - driftAfter (positive = improvement)
timeToResolve: number // Episodes until gap closed (if applicable)
success: boolean // Did the intervention achieve its goal?
notes: string // Optional human annotation
observedAt: DateTime // When outcome was measured
}Outcomes are populated after the fact — the episode is written at the time of action, then updated when the outcome becomes observable. This preserves the temporal integrity of the record.
Episode Decay
Not all episodes are equally relevant over time. GESA applies temporal decay using the WakeIQX model:
EpisodeWeight = BaseWeight × e^(-age/τ)Where τ (the decay constant) is domain-specific:
| Domain | Decay Constant (τ) | Rationale |
|---|---|---|
| Content, Trading | 30 days | Fast-moving; yesterday's conditions don't apply today |
| Workplace, Business Strategy | 180 days | Slower dynamics; historical patterns still relevant |
| Browser Automation | 14 days | Page structures and APIs change frequently |
| Product | 90 days | User behavior shifts seasonally |
Recent episodes carry more weight in retrieval and candidate generation. Historical episodes provide structural pattern recognition but are down-weighted in final selection.
The Production Episode Store
In StratIQX, the episode store was built before GESA was named. The orchestrator_processing_log table in Cloudflare D1 is the production episode schema:
CREATE TABLE orchestrator_processing_log (
id INTEGER PRIMARY KEY,
tracking_id TEXT NOT NULL,
step_name TEXT,
step_number INTEGER,
status TEXT, -- 'started', 'completed', 'failed'
duration_ms INTEGER,
tokens_used INTEGER,
error_message TEXT,
metadata TEXT, -- JSON: model, quality_score, custom_context
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);An active KV buffer (EXECUTION_LOGS, 7-day TTL) sits above D1 for high-recency access — temporal tiering by architecture, not by theory.
This is GESA's episode architecture running in production. The pattern preceded the name.
Cold Start Problem
With zero episodes, GESA cannot retrieve or generate from history. The cold start strategy:
- Seed episodes — import domain-relevant historical data if available
- Prior temperature — start at T = 100 (maximum exploration) until minimum episode threshold reached
- Fallback — return Fetch recommendation without GESA augmentation until episode store is populated
Minimum recommended episode count before GESA outputs are reliable: 20 episodes per domain.