Trust Center

How the scoreboard is produced.

The rules behind every LiftLine AI accuracy figure, including the filters that are not applied and the unvalidated conversion from head counts to minutes.

How the accuracy figures are produced, stated so that someone who wanted to disagree with them would know where to start. The rules we do not apply are listed too, because the absence of a rule is itself a disclosure.

What counts as a scored hour

round(mean(camera-derived wait minutes for that lift-hour union user-reported wait minutes for that lift-hour))

  • An hour is scored only when a numeric forecast and at least one observation both exist for that exact hour.
  • Observations are camera-derived head counts converted to minutes, and skier-submitted waits typed as a number of minutes.
  • Horizon: same-day, issued a median of 1.19 hours after local midnight (roughly 01:11 local) once scheduled generation began. This is NOT a day-ahead forecast.

Rules we apply

These are the rules that ARE applied today, stated exactly. There are fewer of them than a reader would assume.

  1. Scored dates run 2026-04-05 to 2026-06-10. The start is the first whole day on which every camera observation came from the wait conversion still in production and all five scored cameras were live; the end is the last day of continuous scheduled collection. The unwindowed figure is published alongside under all_data.
  2. Only camera observations produced by the current wait conversion count, identified per row by live_crowd.model_regime. Inside the window this excludes exactly one frame; its purpose is to make the rule verifiable rather than to move a number.
  3. Observation window is 06:00-18:00 resort-local on the scored date. Anything outside is dropped.
  4. User wait reports must have report_type = 'wait_minutes' and flagged = false. The abuse filter flags a report whose value is more than 4x the current estimate.
  5. A lift-hour is scored only when a numeric prediction and at least one observation both exist for that exact hour. Everything else silently drops out.
  6. MAPE is computed only over hours whose observed wait is greater than zero, so it never divides by zero. The count of qualifying hours is carried alongside it.

Rules we do not apply, and should

  1. No filter on lift identity. The headline covers every scored lift, including the ones we score worst on. Restricting it to Broadway Express, Face Lift Express and Discovery Chair would move it from 4.18 over 554 hours to 4.02 over 364 hours — a gain of 0.16 minutes for the loss of a third of the sample and of the claim that the number covers everything we measured. It is not done.
  2. No camera-outage filter. If the stream was down there is simply no row, which is handled, but a partially-loaded or stale frame that produced a count is kept.
  3. No obstruction or visibility filter. live_crowd carries a vision confidence and a reference-image match_score; the scorer reads neither. No in-window frame falls below 0.5 confidence, so this costs nothing today, but the rule is still absent.
  4. No snow, fog, or night filter beyond the 06:00-18:00 window.
  5. No filter on whether the ground-truth observation was used to update the prediction being scored. That is exactly what the live_corrected series does, and it is why that series is labeled an estimate, not a forecast.
  6. No exclusion of prediction rows generated after the hour they predict. 70 of 554 in-window baseline hours are affected and are disclosed rather than removed.
  7. No exclusion of camera reconfigurations mid-window. Canyon Express had its crop and match thresholds rewritten on the evening of 2026-04-05 (engine commit abb5116) and its capture resolution dropped on 2026-04-13; the angle matcher was overhauled system-wide on 2026-05-29. Chasing those would make the window a moving target, so they are disclosed instead.

How the figures are pooled

Every headline figure is weighted by scored hours. It is not an average of per-lift-day averages, and it never mixes the day-of forecast with the live-corrected estimate. Pooling those two together is what produced the figure we withdrew in August 2026.

FigureHow it is computed
Average error (MAE)Hour-weighted mean of |predicted − observed| over scored lift-hours.
BiasHour-weighted mean of (predicted − observed). Positive means we over-called the line.
Median and p90Percentiles of the absolute error across scored lift-hours, not across lift-days.
CoverageScored forecast-hours divided by forecast-hours issued in the same window.
Percentage errorComputed only over hours where the observed wait was greater than zero, with the qualifying-hour count carried alongside.

Heads to minutes

Waits are not measured. Head counts are measured, and converted: wait_minutes = round(min(Q / mu, 60)), and 0 when Q <= 10. The head count is a Kalman-smoothed count of people visible in the camera crop. The service rate starts from the published nameplate capacity of the lift and is then updated from observed queue drains.

AssumptionValueWhere it comes fromMeasured?
people_per_hour1500-3600 per liftresort lifts table (nameplate, published by the resort)no
efficiency_preset0.75 high_speed / 0.65 fixed_grip / 0.50 beginnerengine/vision/config.py, cites SAM 'Know Your Capacity' (2018)no
occupancy_rate0.60-0.75 per liftengine/vision/config.py, hand-set per liftno
uptime_preset0.95 high_speed / 0.88 fixed_grip / 0.78 beginnerengine/vision/config.pyno
ZERO_WAIT_THRESHOLD10engine/vision/config.py:140no
QUEUE_MAX_WAIT60engine/vision/config.pyno

mu is the one free parameter. Where enough queue-drain events occurred for the Bayesian estimator to move it, it moved a long way from the asserted prior. Where they did not, the published wait is 100 percent the asserted constant.

LiftAssumed rateLearned rateShiftFrames
Broadway Express24.94/min15.13/min-39.3%1,518
Discovery Chair14.04/min7.45/min-46.9%1,317
Canyon Express24.94/min17.54/min-29.7%642
Face Lift Express19.38/min16.18/min-16.5%466
Village Gondola32.06/min32.06/min0%554
Unbound Express21.38/minnull/minnull%25

Exclusions applied to every public number

Our mountain simulation writes synthetic resorts and synthetic lifts into the same production tables the real collectors write to. Any figure presented as real-world observation excludes them.

NumberExclusion rulesAs of
296,010 — lift-status snapshots, one per lift every 15 minutesresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · scheduled collection only — rows written by ad-hoc backfills, replays, and manual test runs are not counted2026-08-27
4,522 — webcam crowd counts, on the six lift lines a camera actually watchesresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · real camera frames only — synthetic crowd rows generated by the simulator on 2026-08-17 and 2026-08-18 are excluded2026-08-27
6 — lift lines a camera watchesresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · real camera frames only — synthetic crowd rows generated by the simulator on 2026-08-17 and 2026-08-18 are excluded2026-08-27
5 — of those lift lines recorded camera frames inside the scored windowresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · real camera frames only — synthetic crowd rows generated by the simulator on 2026-08-17 and 2026-08-18 are excluded · scoring window 2026-04-05 to 2026-06-10 — scored from the first whole day on which every camera observation came from the wait conversion still in production (the Q/mu drain model that replaced a deleted M/D/1 formula on 2026-04-04) and all five scored cameras were live, through the last day of continuous scheduled collection. The unwindowed figure is published alongside.2026-08-27
170 — lift lines in the catalog, with published specificationsresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation2026-08-27
50 — lift lines mapped to real GPS geometryresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation2026-08-27
4.18 — minutes of mean absolute error on the day-of forecastresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · series = 'baseline' only — the live_corrected series read the observations it is scored against and is never pooled into a forecast figure · scoring window 2026-04-05 to 2026-06-10 — scored from the first whole day on which every camera observation came from the wait conversion still in production (the Q/mu drain model that replaced a deleted M/D/1 formula on 2026-04-04) and all five scored cameras were live, through the last day of continuous scheduled collection. The unwindowed figure is published alongside.2026-08-27
2.11 — minutes — the average line over the same scored hoursresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · series = 'baseline' only — the live_corrected series read the observations it is scored against and is never pooled into a forecast figure · scoring window 2026-04-05 to 2026-06-10 — scored from the first whole day on which every camera observation came from the wait conversion still in production (the Q/mu drain model that replaced a deleted M/D/1 formula on 2026-04-04) and all five scored cameras were live, through the last day of continuous scheduled collection. The unwindowed figure is published alongside.2026-08-27
12.7 — percent of issued forecast-hours that could be scored at allresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · series = 'baseline' only — the live_corrected series read the observations it is scored against and is never pooled into a forecast figure · scoring window 2026-04-05 to 2026-06-10 — scored from the first whole day on which every camera observation came from the wait conversion still in production (the Q/mu drain model that replaced a deleted M/D/1 formula on 2026-04-04) and all five scored cameras were live, through the last day of continuous scheduled collection. The unwindowed figure is published alongside.2026-08-27
12.6 — percent of scored hours that came from prediction rows written after the hour they predictresort_slug <> 'simulator' — the synthetic resort the mountain sim writes into production tables is never counted in a figure presented as real-world observation · series = 'baseline' only — the live_corrected series read the observations it is scored against and is never pooled into a forecast figure · scoring window 2026-04-05 to 2026-06-10 — scored from the first whole day on which every camera observation came from the wait conversion still in production (the Q/mu drain model that replaced a deleted M/D/1 formula on 2026-04-04) and all five scored cameras were live, through the last day of continuous scheduled collection. The unwindowed figure is published alongside.2026-08-27
about one foot — terrain model vertical accuracy at Mammothnone — this figure is a whole-population count with no filter applied2026-08-27

This table is generated from the same declaration the pages render from. It cannot fall out of date with them.

Two data-integrity findings

Found while establishing the window. Both findings affect the all-data figure and are the reason it should never be quoted on its own.

Every off-season scored date is a byte-identical replay of an in-season date.

  • predictions.hourly_predictions payloads are identical (md5) between 2026-03-28 and 2026-06-14/2026-06-15; between 2026-04-25 and 2026-08-09/2026-08-10; and between 2026-05-08 and 2026-08-18/2026-08-23.
  • For 2026-08-18 and 2026-08-23 the predictions.generated_at values are identical to the microsecond (Broadway 08:11:23.745433, Discovery 08:11:29.471445) on two different dates — the same row written twice.
  • live_crowd frames for Broadway (47 frames) and Discovery (45) are byte-identical across 2026-05-08, 2026-08-18 and 2026-08-23: same counts, same waits, same local times-of-day, same sums.
  • All three dates score identically: 14 hours, MAE 6.50, bias +6.50.

In the all-data figure, 2026-05-08 is counted three times. Excluding only the 2026-08-23 copy moves all-data MAE 5.34 -> 5.31. Inside the published window: None. The window ends 2026-06-10, so it contains 2026-05-08 exactly once.

The all-data baseline figure this lane was asked to verify (636 hours, MAE 5.18, bias +4.82) does not reproduce.

Recomputed: 679 hours, MAE 5.34, bias +5.00. The earlier count captured only 14 of the 57 post-season hours — the 2026-08-18 lift-days. The 29 hours on 2026-08-09 and the 14 on 2026-08-23 were missing. Effect on the published window: None. Every one of those hours is excluded by the window on the collection-continuity rule.

How to check us

Every figure names the table and the filter it came from. The machine-readable source for the accuracy figures is a single JSON document produced by a read-only recompute against production, carried into this site with its digest, and rendered without adjustment.

Generated
2026-08-27 — read-only recompute from predictions.hourly_predictions / predictions.live_corrected_hourly vs live_crowd + crowd_reports; ground-truth rule and pooling reproduced from engine/Backend/accuracy_metrics.py
Schema version
2

Figures measured August 27, 2026. Data from the synthetic "simulator" resort is excluded from every number.