---
title: Surface a client notice when a rate column's play population differs from its period
type: task
status: completed
description: >-
  Build the operator-ruled client-side notice for a rate cell whose numerator counts a wider play
  population than its denominator, such as player EPA with two-point conversions over
  per-player-play, reading a shared per-column play-population declaration.
base_uri: user:task/league/data-views/surface-rate-population-mismatch-notice.md
created_at: '2026-10-23T16:16:29.933Z'
entity_id: 71d86f89-eb13-4909-b9ed-974fa8ac176a
finished_at: '2026-10-24T18:50:46.229Z'
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Low
public_read: true
relations:
  - follows [[user:task/league/data-views/pair-player-from-plays-rate-populations.md]]
  - relates [[█████████████████████-██████████-███████████-███-████████-█████████████]]
started_at: '2026-10-24T17:52:11.973Z'
tags:
  - user:tag/league-xo-football.md
updated_at: '2026-10-24T18:50:46.229Z'
visibility_analyzed_at: '2026-11-05T23:49:03.078Z'
---

## Overview

- The operator ruled on 2026-09-11 that a mismatch between a column's play population and its rate period is a user decision surfaced as a CLIENT-SIDE NOTICE, not an annotation and not a moving denominator. It was never built: `app/core/data-views/data-view-notices.mjs` has no such rule.
- Live cases: player EPA counts two-point conversions over fixed per-player-play and action denominators; team both-type measures (EPA, WPA, success, explosive) over `team_pass_play` / `team_rush_play` keep their wide numerator.
- The rate-chip qualifier deferred on 2026-10-21 is the second reader of the same declaration.

## Plan

- [x] Expose each column's play population. The declaration is SEMANTIC, the play types a statistic accumulates on, as the 2026-10-21 ruling asked. `play_type_set` alone cannot say it: team pass yards and team EPA scan the same set. The player factory derives it from role columns and the set. Team, defensive and fantasy-points columns declare it explicitly. Each rate registration declares its denominator population. The server stamps `rate_population_mismatches` on `data_view_metadata`, the same pattern as the admission-dropped notices, so the client holds no second copy. Spec invariants fail a new rate period or rate-capable column that declares nothing.
- [x] Add the `NOTICE_RULES` entry. Two rules: a wider numerator (reads high against its unit) and a partially covered one (reads low), with the second carrying [[user:task/league/data-views/settle-charted-column-rate-denominator.md]]. A column `play_type` and an `output_column_params.play_type` both narrow, so the pinned production views stay silent. League `1e88f9c33`.
- [x] Decide the rate chip. RULED 2026-10-24: no chip qualifier. The notice names each mismatched cell, so a chip qualifier would repeat it. If one is wanted later, it can read the same `rate_population_mismatches` entry.

## Outcome

- Shipped in league `1e88f9c33` (`fb49e42a9` after sync). Deployed in `029a03ded` 2026-10-24, and the data-views cache was flushed.
