Skip to content

Episode Schema

The Data Model Behind GESA

The episode is GESA's atomic unit of memory. Every schema decision below follows from the principles of episodic memory: situatedness, immutability, and temporal context.


Core TypeScript Interfaces

Episode

typescript
interface Episode {
  id:           string          // Unique identifier (UUID)
  timestamp:    DateTime        // When this episode occurred
  context:      EpisodeContext  // What was the situation?
  action:       EpisodeAction   // What was done?
  outcome:      EpisodeOutcome | null  // What happened? (null until observed)
  driftBefore:  number          // Gap before action
  driftAfter:   number | null   // 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
}

EpisodeContext

typescript
interface EpisodeContext {
  domain:       string    // 'content' | 'workplace' | 'trading' | 'browser' | 'business_6d' | 'product'
  dimension:    string    // D1–D6 in 6D context, or domain-specific label
  driftScore:   number    // Gap magnitude at time of decision
  driftSign:    'positive' | 'negative' | 'zero'
  gapVelocity:  number    // Rate of gap change across recent episodes
  fetchScore:   number    // Action confidence score
  chirp:        number    // Signal strength (0–100)
  perch:        number    // Structural confidence (0–100)
  wake:         number    // Temporal context score (0–100)
  tags:         string[]  // Domain-specific contextual labels
  metadata:     Record<string, unknown>  // Domain-specific fields
}

EpisodeAction

typescript
interface EpisodeAction {
  type:         string    // The class of intervention (e.g., 'wip_reduction', 'hook_improvement')
  description:  string    // Human-readable description
  parameters:   Record<string, unknown>  // Domain-specific action parameters
  source:       'gesa_recommended' | 'manual' | 'automatic'
  confidence:   number    // Confidence at time of action (0–100)
}

EpisodeOutcome

typescript
interface EpisodeOutcome {
  driftAfter:       number    // Gap after action (remeasured)
  gapChange:        number    // driftBefore - driftAfter (positive = improvement)
  timeToResolve:    number    // Time units until gap closed (domain-defined)
  success:          boolean   // Did the intervention achieve its goal?
  notes:            string    // Optional human annotation
  observedAt:       DateTime  // When outcome was measured
  confidence:       number    // Confidence in the outcome measurement (0–100)
}

The Production Schema (StratIQX)

The StratIQX production episode store predates the GESA name. It uses Cloudflare D1 for long-term persistence and KV for the active session buffer.

D1 Table

sql
CREATE TABLE orchestrator_processing_log (
    id            INTEGER PRIMARY KEY,
    tracking_id   TEXT NOT NULL,        -- Groups episodes by report run
    step_name     TEXT,                 -- Human-readable episode label
    step_number   INTEGER,              -- Sequential position in the chain
    status        TEXT,                 -- 'started' | 'completed' | 'failed'
    duration_ms   INTEGER,              -- Episode duration
    tokens_used   INTEGER,              -- AI model token consumption
    error_message TEXT,                 -- Failure context (if applicable)
    metadata      TEXT,                 -- JSON: model, quality_score, custom_context
    timestamp     DATETIME DEFAULT CURRENT_TIMESTAMP
);

KV Buffer

Key: EXECUTION_LOGS:{tracking_id} TTL: 7 days Format: JSON array of episode objects for the current session

The KV buffer provides fast access to the active session's episodes. D1 provides long-term pattern recognition. This is GESA's temporal tiering running in production — hot store for recency, cold store for history.


Immutability Pattern

Episodes must be immutable after capture. The production implementation uses:

typescript
// Freeze the episode object at capture time
const episode = Object.freeze({
  id: generateId(),
  timestamp: new Date(),
  context: Object.freeze(contextSnapshot),
  action: Object.freeze(actionRecord),
  outcome: null,  // Not yet observed
  // ...
})

// Outcome update creates a NEW object — does not mutate
function withOutcome(episode: Episode, outcome: EpisodeOutcome): Episode {
  return Object.freeze({
    ...episode,
    outcome: Object.freeze(outcome),
    driftAfter: outcome.driftAfter,
    updatedAt: new Date()
  })
}

The update creates a new immutable object rather than mutating the original. The original capture record is preserved.


Domain-Specific Schema Extensions

Workplace (HEAT)

typescript
interface WorkplaceEpisodeContext extends EpisodeContext {
  domain: 'workplace'
  teamId:          string
  teamSize:        number
  sprintNumber:    number
  sprintPhase:     'early' | 'mid' | 'late'
  painStreakDays:  number
  cognitiveLoad:   number    // 0–100
  contextSwitches: number    // per day
  busFactorRisk:   number    // 0–100
}

Trading

typescript
interface TradingEpisodeContext extends EpisodeContext {
  domain: 'trading'
  instrument:      string
  timeframe:       string    // '1m' | '5m' | '1h' | '4h' | 'D'
  volatilityRegime: 'low' | 'medium' | 'high' | 'extreme'
  marketSession:   string    // 'london' | 'ny' | 'asian' | 'overlap'
  signalType:      string
}

6D Business

typescript
interface BusinessEpisodeContext extends EpisodeContext {
  domain: 'business_6d'
  originDimension:  string    // 'D1' | 'D2' | 'D3' | 'D4' | 'D5' | 'D6'
  cascadePath:      string[]
  cascadeDepth:     number
  fetchTier:        'EXECUTE' | 'CONFIRM' | 'QUEUE' | 'WAIT'
  dimensionScores:  Record<string, number>
}

Episode Decay Constants

typescript
const DECAY_CONSTANTS: Record<string, number> = {
  content:          30  * 24 * 60 * 60 * 1000,  // 30 days
  trading:          30  * 24 * 60 * 60 * 1000,  // 30 days
  browser:          14  * 24 * 60 * 60 * 1000,  // 14 days
  product:          90  * 24 * 60 * 60 * 1000,  // 90 days
  workplace:        180 * 24 * 60 * 60 * 1000,  // 180 days
  business_6d:      180 * 24 * 60 * 60 * 1000,  // 180 days
}

→ API Reference