NeuroReach: score fusion, holds and wire payload

held score ≠ fresh score. Need artifact flag + null sub-scores, and don’t keep updating EMA/normalization while holding

Specified score: IntentScore = w_eeg*EEG_Score + w_kin*Kinematic_Score - Penalty_Compensation, normalized to 0–100. Covert-imagery mode sets w_eeg=1, w_kin=0 and uses observed movement as a validity gate. Blended/active modes are design options with different weights, not evidence that the pending camera path was already delivered.

Smoothing rule: short EMA, approximately 300 ms (alpha≈0.15 at 20 Hz), plus per-session adaptive floor/ceiling. Artifact windows hold the preceding score, set sub-scores null and do not update the EMA or adaptive normalization. A held number must not appear to be a fresh valid observation.

Payload fields:

Sample report: IntentScore timeline and threshold.
Sample report: IntentScore timeline and threshold.

EEG-led, blended and movement-led scoring designs.
EEG-led, blended and movement-led scoring designs.

{"type":"intent_score","intent_score":0,"erd_score":null,
 "classifier_score":null,"is_artifact":true,
 "mode":"band_power_only","timestamp":0}

This is a shape illustration with placeholder values, not a recorded packet. The console separately receives eeg_quality at about 5 Hz; the patient relay is intended to forward only score/game messages.

Code pointers: IntentScoreEngine, threaded ScoringService, NeuroReachWSServer, and patient/console parsers under src/scoring|net/.

Review questions: define score clamping after penalties, stale-message timeout, reconnection behavior and the meaning of timestamps. Keep adaptive difficulty separate from normalization so score trends can be interpreted across sessions.