API Reference

This page is generated automatically from the source docstrings.

Scoring engine

scoring.bart.COLOR_PROFILES

Mapping of each balloon color to its risk tier and maximum pump capacity N: purple (low, N = 128), teal (medium, N = 32), and orange (high, N = 8). Shared throughout the engine.

scoring.bart.MIN_COLLECTED_FALLBACK = 2

Minimum number of collected (non-exploded) balloons a color must have before the engine falls back to using all of that color’s trials for its behavioral-intention metrics.

Public functions

scoring.bart.score_bart(events, config=TaskConfig(schema_version='1.0', title='Dynamic Hazard Rate BART (default dynamic study)', language='en', reward_per_pump=0.25, currency='$', seed=None, output_dir='.', colors=[ColorProfile(name='purple', label='Purple', display_hex='#7c3aed', max_pumps=128, trials=10, hazard=DynamicHazard(family='dynamic')), ColorProfile(name='teal', label='Teal', display_hex='#14b8a6', max_pumps=32, trials=10, hazard=DynamicHazard(family='dynamic')), ColorProfile(name='orange', label='Orange', display_hex='#f97316', max_pumps=8, trials=10, hazard=DynamicHazard(family='dynamic'))], conditions=[], qc=QCThresholds(fast_response_ms=100.0, zero_pump_streak=5), payout=None, exit_passcode=None))[source]

Score a BART session from raw events using NumPy vectorization.

Analyzes behavioral-intention variables using collected (non-exploded) balloons to protect metrics against RNG truncation bias. config supplies the hazard model, per-color EV-optimal stops, and reward; it defaults to the validated 128/32/8 linear study.

Parameters:
Return type:

BARTMetrics

scoring.bart.validate_bart_session(events, config=TaskConfig(schema_version='1.0', title='Dynamic Hazard Rate BART (default dynamic study)', language='en', reward_per_pump=0.25, currency='$', seed=None, output_dir='.', colors=[ColorProfile(name='purple', label='Purple', display_hex='#7c3aed', max_pumps=128, trials=10, hazard=DynamicHazard(family='dynamic')), ColorProfile(name='teal', label='Teal', display_hex='#14b8a6', max_pumps=32, trials=10, hazard=DynamicHazard(family='dynamic')), ColorProfile(name='orange', label='Orange', display_hex='#f97316', max_pumps=8, trials=10, hazard=DynamicHazard(family='dynamic'))], conditions=[], qc=QCThresholds(fast_response_ms=100.0, zero_pump_streak=5), payout=None, exit_passcode=None))[source]

Validate session validity and integrity before scoring.

Completeness and per-color balance are judged against config (the study’s own colors and per-color trial counts), so a renamed or re-counted study is validated against its own shape rather than the default purple/teal/orange 3x10 study (issue 57).

Checks performed: 1. Minimum balloon count 2. Balanced representation of risk profiles (colors) 3. Timestamp monotonicity 4. Session pacing (unusual completion speeds) 5. Pump variance (automated/bot-like uniform inputs)

Parameters:
Return type:

dict[str, Any]

Internal computation helpers

The functions below are private (underscore-prefixed) implementation details. They are documented here as a technical reference for the metric definitions; they are not part of the public API and may change between releases.

scoring.bart.trial_table(events, config=TaskConfig(schema_version='1.0', title='Dynamic Hazard Rate BART (default dynamic study)', language='en', reward_per_pump=0.25, currency='$', seed=None, output_dir='.', colors=[ColorProfile(name='purple', label='Purple', display_hex='#7c3aed', max_pumps=128, trials=10, hazard=DynamicHazard(family='dynamic')), ColorProfile(name='teal', label='Teal', display_hex='#14b8a6', max_pumps=32, trials=10, hazard=DynamicHazard(family='dynamic')), ColorProfile(name='orange', label='Orange', display_hex='#f97316', max_pumps=8, trials=10, hazard=DynamicHazard(family='dynamic'))], conditions=[], qc=QCThresholds(fast_response_ms=100.0, zero_pump_streak=5), payout=None, exit_passcode=None))[source]

The session as long-format trial rows: one record per balloon (issue 39).

This is the row shape of the study-wide trials CSV, computed here — not re-derived in the sidecar — so CLI users of scoring get the same trial table. A trailing balloon without a terminal event (an aborted session) has no outcome and is omitted.

Parameters:
Return type:

list[TrialRecord]

Data schemas

BART Event & Metrics Schemas — Self-Contained Pydantic Models

Defines the data models for BART game events and scoring output. This is a standalone package — no external schema dependencies required.

Models:

GameEvent — A single timestamped event (pump, collect, explode) EventPayload — Flexible payload attached to each event GameSession — Complete session with ordered event log ColorMetrics — Per-color scoring breakdown BARTMetrics — Full scoring output from score_bart()

class scoring.schemas.GameType(*values)[source]

Bases: str, Enum

Supported cognitive assessment game types.

class scoring.schemas.EventPayload(*, balloon_id=None, color=None, balloon_color=None, stimulus=None, response=None, position=None, **extra_data)[source]

Bases: BaseModel

Flexible payload attached to each event.

Each game type defines its own payload shape. Using model_config extra=”allow” for extensibility.

Parameters:
  • balloon_id (int | None)

  • color (str | None)

  • balloon_color (str | None)

  • stimulus (str | None)

  • response (str | None)

  • position (int | None)

  • extra_data (Any)

model_config = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.GameEvent(*, timestamp, type, payload=<factory>)[source]

Bases: BaseModel

A single timestamped event from a game session.

This is the atomic unit of data collected from the frontend. Timestamps use performance.now() (ms since page load) for sub-millisecond precision.

Parameters:
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.GameSession(*, session_id, game_type, candidate_id='anonymous', condition=None, duplicate_acknowledged=False, practice=False, events)[source]

Bases: BaseModel

Complete game session payload received from the frontend.

Contains the full ordered event log for server-side scoring.

Parameters:
classmethod events_must_be_chronological(v)[source]

Validate that events are in chronological order.

Out-of-order timestamps indicate either client tampering or a corrupted event stream — reject with 422.

Parameters:

v (list[GameEvent])

Return type:

list[GameEvent]

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.ColorMetrics(*, color, average_pumps, behavioral_avg_pumps=0.0, explosion_rate, total_balloons, collected_count=0, risk_profile, used_fallback=False, ev_efficiency=None, ev_optimal_stop=None, excess_explosion_rate=None)[source]

Bases: BaseModel

Per-color metrics for multi-risk BART profiles.

Parameters:
  • color (str)

  • average_pumps (float)

  • behavioral_avg_pumps (float)

  • explosion_rate (float)

  • total_balloons (int)

  • collected_count (int)

  • risk_profile (str)

  • used_fallback (bool)

  • ev_efficiency (float | None)

  • ev_optimal_stop (int | None)

  • excess_explosion_rate (float | None)

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.TrialRecord(*, trial, balloon_color, hazard_family=None, pumps, outcome, trial_earnings, mean_latency_between_pumps=None)[source]

Bases: BaseModel

One trial (balloon) of a session in long format (issue 39).

The row shape of the study-wide trials CSV — identity columns are added by the writer; this model carries the design + behavior columns the scoring engine computes from the event log. Field names follow the canonical BART nomenclature so the file reads without a codebook.

Parameters:
  • trial (int)

  • balloon_color (str)

  • hazard_family (str | None)

  • pumps (int)

  • outcome (Literal['collected', 'exploded'])

  • trial_earnings (float)

  • mean_latency_between_pumps (float | None)

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.BARTMetrics(*, average_pumps_adjusted, explosion_rate, mean_latency_between_pumps, total_balloons, total_pumps, total_explosions, total_collections, color_metrics=<factory>, learning_rate=0.0, risk_adjustment_score=0.0, color_discrimination_index=None, rng_normalized_pumps=0.0, orange_avg_pumps=None, patience_index=0.0, response_consistency=0.0, adaptive_strategy_score=0.0, risk_sensitivity=0.0, behavioral_profile=<factory>, impulsivity_index=0.0, avg_pumps_all_balloons=0.0, patience_index_normalized=0.0, half_split_learning_rate=0.0, within_balloon_consistency=0.0, between_balloon_consistency=0.0, ev_ratio_score=0.0, explosion_penalty=0.0, risk_calibration_score=0.0, ev_efficiency_uniformity=None, money_collected=0.0, money_efficiency=0.0, flat_strategy_detected=False, color_discrimination_trajectory=None, post_explosion_sensitivity=None, tercile_learning_rate=0.0, ev_optimal_stops=<factory>, session_valid=True, session_warnings=<factory>, qc_fast_response_trials=0, qc_zero_pump_streak=0, qc_flagged=False, qc_fast_response_ms=100.0, qc_zero_pump_streak_threshold=5, payout_amount=None, payout_currency=None)[source]

Bases: BaseModel

Computed metrics from a BART game session.

Parameters:
  • average_pumps_adjusted (float)

  • explosion_rate (float)

  • mean_latency_between_pumps (float)

  • total_balloons (int)

  • total_pumps (int)

  • total_explosions (int)

  • total_collections (int)

  • color_metrics (list[ColorMetrics])

  • learning_rate (float)

  • risk_adjustment_score (float)

  • color_discrimination_index (float | None)

  • rng_normalized_pumps (float)

  • orange_avg_pumps (float | None)

  • patience_index (float)

  • response_consistency (float)

  • adaptive_strategy_score (float)

  • risk_sensitivity (float)

  • behavioral_profile (dict[str, Any])

  • impulsivity_index (float)

  • avg_pumps_all_balloons (float)

  • patience_index_normalized (float)

  • half_split_learning_rate (float)

  • within_balloon_consistency (float)

  • between_balloon_consistency (float)

  • ev_ratio_score (float)

  • explosion_penalty (float)

  • risk_calibration_score (float)

  • ev_efficiency_uniformity (float | None)

  • money_collected (float)

  • money_efficiency (float)

  • flat_strategy_detected (bool)

  • color_discrimination_trajectory (float | None)

  • post_explosion_sensitivity (float | None)

  • tercile_learning_rate (float)

  • ev_optimal_stops (dict[str, float])

  • session_valid (bool)

  • session_warnings (list[str])

  • qc_fast_response_trials (int)

  • qc_zero_pump_streak (int)

  • qc_flagged (bool)

  • qc_fast_response_ms (float)

  • qc_zero_pump_streak_threshold (int)

  • payout_amount (float | None)

  • payout_currency (str | None)

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.NormalizedScore(*, metric_name, raw_value, z_score, percentile, population_mean, population_std)[source]

Bases: BaseModel

A raw metric normalized against population norms.

Parameters:
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class scoring.schemas.AssessmentResponse(*, session_id, game_type, candidate_id, raw_metrics, normalized_scores, profile_traits=<factory>)[source]

Bases: BaseModel

Full response after scoring and norming an assessment.

Parameters:
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Event validators

BART Event Validators

Usage:

from scoring.schemas.game_events import validate_bart_events

class scoring.schemas.game_events.TrialRecord(*, trial, balloon_color, hazard_family=None, pumps, outcome, trial_earnings, mean_latency_between_pumps=None)[source]

One trial (balloon) of a session in long format (issue 39).

The row shape of the study-wide trials CSV — identity columns are added by the writer; this model carries the design + behavior columns the scoring engine computes from the event log. Field names follow the canonical BART nomenclature so the file reads without a codebook.

Parameters:
  • trial (int)

  • balloon_color (str)

  • hazard_family (str | None)

  • pumps (int)

  • outcome (Literal['collected', 'exploded'])

  • trial_earnings (float)

  • mean_latency_between_pumps (float | None)

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].