Skip to main content
The behavior SDK does not compute these metrics in Dart/Kotlin/Swift directly. The canonical implementation runs inside the runtime’s behavior feature deriver — the SDK ships events and the runtime returns metric bundles. Apps see the results as fields on BehavioralMetrics inside BehaviorSessionSummary.

Window

A metric is computed either:
  • Over the entire session (default, returned in BehaviorSessionSummary.behavioralMetrics).
  • Over an arbitrary time range when you call calculateMetricsForTimeRange({startTimestampSeconds, endTimestampSeconds, sessionId?}).
When the window contains no events, every metric returns 0.0 and lists return empty.

The canonical 12

interactionIntensity

interruption_events = notification_events + call_events + app_switch_events. Range [0, 1]. Anchored so ~10 events/min reads as full intensity.

taskSwitchRate

Exponential saturation:
2 switches/min ≈ 0.63; high rate approaches 1.

taskSwitchCost

In the SDK, BehavioralMetrics.taskSwitchCost is the millisecond form (raw int); flux internally also exposes a normalised [0, 1] version.

idleTimeRatio

Idle gaps are counted from the SDK’s idle-segment detector (gaps above the configured threshold).

activeTimeRatio

Note: this is not simply 1 − idle_time_ratio — task-switch cost is also subtracted.

notificationLoad

Exponential saturation:
1 notification/min ≈ 0.63.

burstiness

Barabási burstiness over inter-event gaps:
0.0 = perfectly regular (Poisson-like), 0.5 = random / no data, 1.0 = very bursty. Flux returns 0.5 when the session has no inter-event gaps yet.

behavioralDistractionScore

Weighted composite, fixed weights:
The four weights are constants in flux; they are not configurable per session.

focusHint

By construction, focusHint + distractionScore = 1.0. (Flux’s test test_focus_hint_is_inverse_of_distraction enforces this.)

fragmentedIdleRatio

Note: the raw ratio can exceed 1.0 on very short sessions; flux clamps at the encoding step before HSI export.

scrollJitterRate

A direction reversal counts when scrolling flips between up and down.

deepFocusBlocks

Engagement segments lasting at least DEEP_FOCUS_MIN_DURATION_SEC = 120 seconds (2 minutes), fixed in flux. Each block in the SDK shape:
Flux internally returns just the count; the SDK enriches it with timing detail when constructing BehaviorSessionSummary.

Typing metrics (extension)

When a session contains typing events, the SDK adds TypingMetrics derived from typing-specific aggregations (formulas live in flux’s typing module): A few are defined as composite ratios (commented in behavior_gesture_detector.dart):
  • typing_interaction_intensity = w₁ · typing_speed_norm + w₂ · (1 − typing_gap_ratio) + w₃ · typing_cadence_stability (weights set in the runtime feature deriver).
  • clipboard_activity_rate = (copy + paste + cut) / (typing_taps + clipboard_actions).
  • correction_rate = (backspace + delete) / (typing_taps + backspace + delete).

NotificationSummary

Numerical stability

Flux clamps:
  • All bounded outputs are wrapped in .clamp(0.0, 1.0) (or per-field bounds for raw mileage values like task_switch_cost_ms capped at 10000).
  • Empty input (no events, zero duration, no scrolls, etc.) returns the safe fallback (0.0 for ratios, 0.5 for burstiness).
If a metric ever surfaces outside its declared range, it’s a bug in flux — not a value to interpret.