Understanding State

Abstract time-series visualization on a monitor

At the heart of Behavioral Pathways is a single abstraction: StateValue. This structure represents everything from mood dimensions to personality traits to trust levels. Understanding StateValue means understanding how the entire system thinks about psychological state.

The Core Abstraction

pub struct StateValue {
    base: f32,              // Stable tendency (who you are)
    delta: f32,             // Current deviation (what just happened)
    chronic_delta: f32,     // Persistent deviation (what keeps happening)
    decay_half_life: Duration,
}

Every psychological dimension in the system is a StateValue. Mood valence, extraversion, trust in a specific person, need for belonging: all the same structure. This uniformity is intentional. It encodes our core belief about psychological state:

Everything is a stable tendency plus temporary deviations that decay over time.

Base: Who You Are

The base value represents the stable, long-term tendency. For personality traits, this is what you would measure on a validated instrument: someone's baseline extraversion, their typical anxiety level, their default trust disposition. The base changes slowly, if at all, and only in response to significant life events.

In psychological terms, base captures trait-level constructs. These are the patterns that persist across situations and time, the things that make you recognizably you even as specific moods and circumstances fluctuate.

Delta: What Just Happened

The delta value represents temporary deviation from baseline. A bad day creates a negative mood delta. A compliment creates a positive self-esteem delta. These deviations are real and meaningful in the moment, but they decay.

Delta captures state-level constructs: the situational variations that overlay stable traits. You might be a generally happy person (high base valence) having a bad day (negative delta valence). Both facts are true simultaneously.

Chronic Delta: What Keeps Happening

The chronic_delta represents persistent environmental pressure. If you are in a stressful job, you might have a chronic negative delta on mood even though your base tendency is toward happiness, and even though no specific recent event is driving it.

This component handles situations where the environment maintains constant pressure without discrete events. It decays when you leave that environment, but slower than acute deltas.

The Effective Value

At any moment, the effective value is:

effective = base + delta + chronic_delta

This is what you observe. When you interact with someone, you experience their effective mood, not their base mood. When you assess your own anxiety, you feel the combination of trait anxiety and state anxiety together.

The Philosophy of Decay

Everything decays. This is perhaps the most important design decision in the system.

When an event creates a delta, that delta begins decaying immediately. The rate is controlled by decay_half_life: after one half-life, the delta is half its original value. After two half-lives, one quarter. The decay is exponential.

Exponential decay curve with event spikes and recovery
// Delta after time t
remaining_delta = initial_delta * (0.5 ^ (t / half_life))

This models psychological reality: emotional responses fade. The sharp sting of criticism softens over days. The glow of praise dims over weeks. You return to baseline.

Why Exponential Decay?

We chose exponential decay because:

  • It matches empirical data: Studies of emotional recovery show exponential-like return to baseline
  • It is mathematically tractable: We can compute state at any time without simulating intermediate steps
  • It is memory-efficient: We only need to store the initial delta and timestamp, not the full history
  • It composes well: Multiple decaying deltas from different events can be summed

The half-life varies by domain. Mood deltas might have half-lives of hours to days. Trust deltas might have half-lives of weeks to months. Personality-affecting events have the longest half-lives because they represent the most enduring changes.

Two Pathways for Change

StateValue supports two fundamentally different types of change: short-term and long-term.

Short-Term Pathway: Delta Accumulation

Most events create deltas. A stressful meeting adds negative valence delta. A good conversation adds positive delta. These accumulate: multiple events in succession create compounding effects.

// Event creates a delta
fn apply_event(&mut self, event: &Event) {
    let impact = compute_impact(event, self);
    self.delta += impact;
    // Delta will decay from here
}

This pathway handles the texture of daily life. Moods fluctuate. Trust waxes and wanes. The underlying person remains stable; their state varies.

Long-Term Pathway: Base Shifts

Some events are formative: they change who you are, not just how you currently feel. Trauma, profound experiences, major life transitions. These shift the base value.

// Formative event shifts base
fn apply_formative_event(&mut self, event: &FormativeEvent) {
    let shift = compute_shift(event, self);
    if shift.abs() > FORMATIVE_THRESHOLD {
        self.base += shift * SETTLING_CURVE;
    }
}

Base shifts follow a settling curve, not immediate application. This models how transformative experiences have immediate impact but then settle to a permanent change that is less than the acute effect. The research on post-traumatic growth and personality change after major life events supports this pattern.

The FORMATIVE_THRESHOLD

Not every event is formative. We set a threshold (typically 0.20 on a normalized scale) below which events only create deltas. Above this threshold, the event also shifts base.

This means severe events have two effects: a large delta that will decay, and a smaller base shift that persists. A traumatic rejection creates acute emotional pain that fades, plus a lasting increase in anxiety baseline.

Temporal Queries

One of the most powerful features of StateValue is temporal queryability. You can ask: "What was this entity's mood at time T?" without storing a history of mood values.

Timeline with event markers fading over time

How It Works

We store events with timestamps. To compute state at any time T:

  1. Start with the base value at the anchor timestamp
  2. For each event before T, compute its impact and how much it has decayed by T
  3. Sum all decayed deltas
  4. Add any base shifts from formative events before T
fn state_at(&self, timestamp: Timestamp) -> f32 {
    let mut value = self.base_at(timestamp);

    for event in self.events_before(timestamp) {
        let delta = event.compute_delta(self);
        let elapsed = timestamp - event.timestamp;
        let decayed = delta * decay_factor(elapsed, self.decay_half_life);
        value += decayed;
    }

    value
}

No Stored History

This is the key insight: we do not store historical state. We store events and compute state on demand. This has several advantages:

  • Query flexibility: Ask about any timestamp, past or future
  • Memory efficiency: Only events are stored, not computed states
  • Retroactive updates: Adding a past event automatically updates all derived states
  • Determinism: Same events always produce same state (no accumulated floating-point error)

Forward and Backward Queries

You can query in either direction. "What was mood yesterday?" and "What will mood be tomorrow?" use the same mechanism. For future queries, we project current deltas decaying forward.

This enables predictive scenarios: "If no new events occur, how will this entity feel in a week?" The answer is: current delta decayed by one week, approaching base.

Unification Under One Model

StateValue unifies phenomena that are often modeled separately:

  • Mood: Short half-life, high delta sensitivity
  • Personality: Long/infinite half-life, rare base shifts
  • Trust: Medium half-life, relationship-specific
  • Needs: Domain-specific half-lives, continuous pressure via chronic_delta

By using the same abstraction, we can apply the same computational machinery uniformly. Query mood at time T? Query trust at time T? Same operation. This uniformity simplifies the codebase and the mental model.

Implementation Details

Clamping and Normalization

StateValues are typically normalized to [-1, 1] or [0, 1] ranges depending on the dimension. Valence (mood) uses [-1, 1] (very negative to very positive). Trust uses [0, 1] (no trust to complete trust). The system clamps effective values to valid ranges.

Event Ordering

Events are processed in timestamp order. When two events have identical timestamps, we use stable sort to preserve insertion order. This matters because some events might depend on state created by earlier same-timestamp events.

Performance Considerations

Temporal queries are O(n) in the number of events before the query timestamp. For simulations with many events, we implement several optimizations:

  • Decay truncation: Events whose delta has decayed below epsilon are skipped
  • Checkpoint snapshots: For frequently-queried timestamps, we cache computed state
  • Event pruning: Very old events with fully-decayed deltas can be collapsed into base adjustments

Working with StateValue

When using the system, keep these principles in mind:

  • Base is precious: Do not shift base casually. Most events should only create deltas.
  • Half-lives matter: Choose them based on the psychological domain. Fast for mood, slow for personality.
  • Think in effective values: Users experience effective state, not base. High base with large negative delta is still a bad mood.
  • Leverage temporal queries: Do not store snapshots manually. Query state at the times you need it.

The StateValue abstraction is simple, but it encodes a sophisticated model of psychological dynamics. Master it, and you understand the core of Behavioral Pathways.