Skip to content

Metrics β€” full reference

This page defines every NEXORA metric: what it represents, what it is for, its exact formula, input data, unit/rounding, thresholds and colors, absence cases and the source module of the computation.

Source of truth: lake/gold (Parquet) read via DuckDB β€” never duplicated nor invented in the UI. Contract rule: rounding applies to display only, never to storage.


Engagement

What it is β€” the general engagement level of the class (or a student) over the lesson: the average of the 15 s observation window scores, on a 0–10 scale converted to %.

What it is for β€” the master metric: all the others derive from it. A low % signals a globally disengaged lesson; compared across subjects or sessions, it measures the trend.

Computation β€” average of the valid windows' engagement_score:

engagement_pct = AVG(engagement_score) Γ— 10

Input: gold/class_session.engagement_pct, gold/student_session.avg_engagement_score.

Unit / rounding: percent, rounded to integer (display).

Thresholds / colors:

Score Level Color
β‰₯ 8.1 Deep Engagement forest green
6.6 – 8.0 Active Engagement sage green
4.6 – 6.5 Passive Presence pale green
2.6 – 4.5 Disengagement orange
< 2.6 Withdrawal red

Absence: no valid window β†’ β€œdata unavailable”, excluded from averages.

Example: class of 31 students, 20 windows β‰₯ 6.6 out of 30 β†’ 66 %.

Source: processing/pipelines/scoring.py, polars_pipeline.py::_class_session, web/src/lib/server/gold.ts.


Sustained attention

What it is β€” the longest continuous run of β€œengaged” windows (score β‰₯ 6.6/10), converted to minutes.

What it is for β€” signals the capacity for prolonged concentration: a student who holds 12 min without disengaging may have an average average but good maintenance capacity.

Computation β€” longest run of engagement_score >= 6.6, converted:

run = run + 1 if score >= 6.6 else 0
sustained_attention_min = max(run) Γ— 15 s / 60

Unit / rounding: minutes, 1 decimal.

Source: polars_pipeline.py::_student_session.


On-task

What it is β€” the share of windows where the gaze is directed toward the task (label A1 = on-task gaze): board, notebook, teacher… rather than distracted or head down.

What it is for β€” measure visible attention, independently of the score feeling: an β€œon-task” student is looking at the learning material.

Computation:

on_task_ratio = COUNT(A == 'A1') / COUNT(windows)

Unit / rounding: percent, integer.

Thresholds: β‰₯ 65 % green, 46–65 % orange, ≀ 45 % red.

Source: scoring.py::score_attention, student_session.on_task_ratio.


Attention shifts

What it is β€” the number of on-task β†’ off-task transitions: moves from an A1 window to a non-A1 window.

What it is for β€” detect attentional instability: many β€œjumps” signal fragmented attention, even if on-task time stays correct.

Computation:

attention_transitions = SUM(prev == 'A1' and cur != 'A1')

Unit / rounding: count, integer.

Threshold: > 8 transitions β†’ orange (unstable).

Source: student_session.attention_transitions.


Drift

What it is β€” the total cumulative off-task time (gaze A2 off-task or A4 prolonged stare).

What it is for β€” quantify disengagement: 5 min of drift in an hour = 8 % of time lost to distraction.

Computation:

drift_total_sec = COUNT(A IN ('A2','A4')) Γ— 15 s

Unit / rounding: minutes, integer.

Threshold: > 5 min β†’ orange.

Source: student_session.drift_total_sec, class_session.avg_drift_sec.


Recovery

What it is β€” the average number of windows needed to come back on-task (A1) after a drift episode.

What it is for β€” the recovery speed: 1–2 windows = good self-regulation;

3 windows = difficulty getting back to work.

Computation β€” average of the delays (in windows) between the end of the drift episode and the return to A1:

recovery_speed_windows = MEAN(return delays, in windows)

The drift window itself is not counted: we measure the return, not the drift duration. If the student never comes back on-task, the episode is not part of the average (or is flagged β€œno return” depending on the version).

Unit / rounding: number of windows, 1 decimal.

Threshold: > 3 windows β†’ orange.

Source: student_session.recovery_speed_windows.


Flags

What it is β€” the number of students (class) or the status (student) who triggered at least one immediate flag.

What it is for β€” priority alert: the first thing a teacher looks at after the lesson.

Triggers: A5+B4/B5 (head down + idle), A4+B4+C3/C4 (stare + slouching), G2 (no response to a cue), β‰₯ 3 yawns (D1), > 3 min of social distraction (A2/A3 + F3).

Unit: number of students (counter) β€” never mix with a percentage on the same axis (use flagged_pct for the share of measured students).

Source: scoring.py::window_flags, student_session.flags/flagged.


Fatigue

What it is β€” the yawn counter (D1) over the lesson.

What it is for β€” somatic fatigue signal: β‰₯ 3 yawns triggers the FLAG_FATIGUE flag.

Computation: COUNT(D == 'D1').

Unit: count, integer. Threshold: β‰₯ 3 β†’ flag.

Source: student_session.yawn_count.


Social flag

What it is β€” the time spent in social distraction: off-task gaze (A2/A3) and off-task social interaction (F3) simultaneously.

What it is for β€” identify students who disengage by talking to their neighbors rather than daydreaming alone.

Computation:

social_distraction_sec = COUNT(A IN ('A2','A3') AND F == 'F3') Γ— 15 s

Threshold: > 180 s β†’ FLAG_SOCIAL_DISTRACTION flag.

Source: student_session.social_distraction_sec.


Synchrony

What it is β€” the class synchrony: % of windows where the majority of students are engaged at the same time.

What it is for β€” measure the collective rhythm of the lesson: a class synchronized at β‰₯ 70 % follows the same pedagogical tempo.

Computation (DuckDB SQL on gold/timeline):

AVG(CAST(synchronized AS DOUBLE)) * 100

Unit / rounding: percent, integer. Threshold: β‰₯ 70 % = β€œhigh”.

Source: gold.ts::lessonMetrics.


Domains

What it is β€” the simplified view of the student profile in 6 domains: Attention, Task, Participation, Distraction, Affect, Comfort.

What it is for β€” quick read of strengths/weaknesses, without jargon (RightPanel component).

Computation β€” aggregation of the A–G category scores: Attention=A, Task=B, Participation=B/F, Distraction=D, Affect=E, Comfort=C.

Units: score /100. Colors: β‰₯ 65 green, 46–64 orange, ≀ 45 red (inverted for Distraction).

Source: gold.ts::toStudentRow (scores).


Levels

What it is β€” the classification into the 5 official engagement levels.

Level Range (/10) Badge
Deep Engagement 8.1 – 10.0 Active
Active Engagement 6.6 – 8.0 Quiet
Passive Presence 4.6 – 6.5 Passive
Disengagement 2.6 – 4.5 Bored
Withdrawal 0.0 – 2.5 Frustrated

What it is for β€” the common vocabulary of the platform (student table badges, automatic interpretations, recommendations).

Source: scoring.py::LEVELS, gold.ts::LEVELS.


Phase-1 attention metrics

What it is β€” the group of 6 β€œAttention metrics” tiles in the student panel: On-task, Shifts, Drift, Recovery, Episodes, Yawns β€” all defined above.

What it is for β€” quick read of the attentional behavior outside the global score: a student can be β€œengaged” on average but with many short drift episodes (unstable) β€” visible here, not in engagement.

Source: student_session (on_task_ratio, attention_transitions, drift_episodes, drift_total_sec, recovery_speed_windows, yawn_count).