Session Weather

August 9, 2026 · View on GitHub

Session weather is a health indicator shown on each session card. It condenses eight independent signals into a single score, displayed as an emoji (sunny through stormy) with a hover tooltip that lists the active factors.

Source of truth: public/weather.js.

Signals

SignalWhat it watchesSeverity curveCapMin turns
ctx_pressureLast turn's context fill %40% → 0, 100% → 1.0 (linear)1.01
compaction_scarNumber of compacted turns1 = 0.4, 2+ = 0.60.61
truncationAny turn hit max_tokens (≥16K output)Fixed 0.50.51
stuckLongest consecutive tool-failure streak≥10 = 0.9, else 00.910 consecutive
latency_driftp75 of last 10 turns vs model baseline1x → 0, 3x → 1.01.05
error_cluster5-turn sliding window tool error raterate / 2.00.53 tool_use in window
error_cumulativeSession-wide tool error ratio20% → 0.5, 40% → 1.01.010 tool turns
cache_healthMedian cache hit rate (last 10 turns, skip first 3)50% → 0, 0% → 0.50.53 qualifying

Signal tiers

Severity caps encode relative importance:

  • Functional (cap 0.9–1.0): ctx_pressure, stuck, error_cumulative, latency_drift — directly affect whether the agent can complete its work.
  • Quality (cap 0.5–0.6): compaction_scar, truncation, error_cluster — the agent runs but information or quality is degraded.
  • Cost/efficiency (cap 0.5): cache_health — functionality unaffected; the session costs more and runs slower.

Provider scope

cache_health only applies to Anthropic entries (provider === 'anthropic' or absent). OpenAI/Codex and xAI/Grok entries are skipped because their wire parsers normalize cache fields differently.

Score composition

score = max(severities) + 0.3 * second(severities)

Only the two highest severities contribute. This prevents multiple low-severity signals from stacking into a false alarm.

Levels

Score rangeLevelEmojiMeaning
< 0.35sunny☀️Operating normally
< 0.55fair🌤️Minor signals, no action needed
< 0.75cloudyQuality starting to degrade
< 0.95rainy🌧️Significantly degraded, take action
≥ 0.95stormy⛈️Critically degraded, act now

Tooltip

The hover overlay shows different content depending on the level:

  • Sunny / Fair: stats proving health — context %, error count, cache hit rate, latency ratio, compaction count.
  • Cloudy / Rainy / Stormy: active factors sorted by severity, plus an action line linking to the relevant turns (when available).

Display toggle (2.3.1)

Weather display is off by default since 2.3.1. Computation and persistence continue running — sessions.json keeps accumulating weather objects — but the six render sites (session card emoji, lane label, turn tooltip Health row, agent card emoji, turn card emoji, and Turn failure rate) are gated behind weatherDisplayEnabled().

The tool-failure signals (stuck, error_cluster, error_cumulative, tool_failure) are currently unreliable across all data paths: Anthropic proxy reads cumulative toolFail (~16× inflation), imported data has no signal (74% of entries), and the OpenAI-wire decoders have known defects. See #484 for details. The remaining five signals (ctx_pressure, compaction_scar, truncation, latency_drift, cache_health) are unaffected but share the same emoji, so the entire display is hidden.

Toggling on for inspection

  • URL param (one-shot, survives SPA navigation via load-time latch): append ?weather=on to the dashboard URL.
  • localStorage (persistent per browser): localStorage.setItem('ccxray-weather-display', 'on') in the console, then reload. Set to 'off' or remove the key to revert.
  • Program default: _weatherDisplayDefault in public/weather.js. Will be flipped to true once the tool-failure signals are fixed and recalibrated (#487).

Cold-start immunity

Each signal has a minimum-turns requirement to avoid firing on incomplete data. cache_health additionally skips the first three turns of the session (prompt cache cold start — Math.max(3, len - 10)) and ignores turns with fewer than 1,000 input tokens. For sessions longer than 13 turns the full trailing 10 are examined; shorter sessions only see turns after the cold-start boundary.