---
title: Add available opportunity, route share and snap share to the utilization components
type: task
status: completed
description: >-
  Shipped the available-opportunity atom and route-share and snap-share components as one-atom
  composite columns, with composites refusing (NULL) any scope before their first covered season.
  The holdout benchmark shows no predictive improvement over the Utilization Score.
base_uri: user:task/league/add-available-opportunity-to-utilization-components.md
created_at: '2026-09-23T19:43:15.390Z'
entity_id: c2130a53-16d3-4591-a7d4-acedf70f986d
finished_at: '2026-10-10T06:09:31.629Z'
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Low
public_read: true
relations:
  - blocked_by [[██████████████████████-██████-███████████-████████]]
  - follows [[██████████████████████-███████████-████████]]
  - relates [[████████████████████████-████-███████████-████████]]
tags:
  - user:tag/league-xo-football.md
  - user:tag/software-task.md
updated_at: '2026-10-10T06:09:31.942Z'
visibility_analyzed_at: '2026-11-05T23:48:08.131Z'
---

## Overview

Add the available-opportunity atom to the utilization components and expose route share and snap share as first-class components beside it, so a receiver who runs routes and draws no targets reads as a role rather than as nothing.

**Shipped 2026-10-10 at league `dbff66475`.** Three atoms join the realized one in `libs-server/data-views/measure/opportunity-atoms.mjs`, each exposed as a one-atom composite column: `player_available_expected_fantasy_points_share_from_plays`, `player_route_share_from_plays`, `player_snap_share_from_plays`. The atom layering, the registered atoms and the coverage refusal are documented in [[user:text/league/data-views/measure-contract.md]]; the benchmark result is in [[████████████████████████-████-███████████-████████]].

## Design as built

- **Available opportunity** is `SUM over routes of P(targeted | route) * E[stats | targeted]`, with the four `available_expected_*` stats on `nfl_player_route_target_probability` scored per league format at query time. A new AVAILABLE scoring variant weights the flat `targets` term by the target probability rather than scoring a whole target per route. First season is read from the estimator artifact (2025), so a refit moves it.
- **Route share** is dropbacks with a route over non-penalty dropbacks, read from the route population table rather than the route view: the view's charting leg is estimated at about 4,000 rows against 130,000 real, and a two-season join to it timed out. 2025 onward.
- **Snap share** is offensive snaps on the field over offensive snaps, from `nfl_snaps` through the cohort member's own pid. 2016 onward.
- **Coverage.** Each atom NULLs, in both halves, plays before its first season and plays or games its source has not measured. A composite (every component column is one) refuses with NULL any scope holding a play before its derived first season, via an `uncovered_plays` accumulator, so a straddling window cannot blend two spans.
- **Batched scans.** Columns sharing a cohort scan now get the union of their measure joins at both grains; previously the season builder applied only the last column's and the period batch only the first's.

## Plan

### Components

- [x] **Build the `E[expected receiving points | targeted]` estimator** — delivered by [[██████████████████████-██████-███████████-████████]]. Verified 2026-10-10 per stat in one pass: corrected construction within 1 percent on every stat for 2025 and 2026 (PPR +0.02 / -0.01 percent); naive control -10.64 / -14.64 percent.
- [x] **Add the available-opportunity atom.** All 1,172 zero-target 2025 player-games with routes read available above zero; the realized control reads zero on every one. 58.0 percent of 2025 player-games sit below available.
- [x] **Add route share and snap share as components.** Route share against `player_receiving_gamelogs.route_share`, 1,250 player-games in weeks 3-6 of 2025: median absolute difference 3.3 points, 87 percent within 10, signed bias -3 to -5 by position. Explained: dropback denominators agree to within one or two plays; the gamelog route count tracks the charting's `PASS ROUTE` rows, ours requires a charted route type.
- [x] **Enforce per-atom coverage resolution in composites.** Live: a 2024 or 2024-2025 query returns NULL for both 2025-first components and values for realized and snap share; spec `data-views.composite-measure.spec.mjs` executes the refusal. The degraded-season ruling holds: 2024 returns NULL, never a bare value.

### Validation

- [x] **Re-run the holdout benchmark with the available-opportunity term.** No improvement: available share -0.1695 (CI -0.2122 to -0.1272) and the equal blend -0.0372 (CI -0.0552 to -0.0205) against the Utilization Score; a post-hoc rushing-kept variant -0.0167 (CI -0.0342 to +0.0012).
- [x] **Population-level non-degeneracy.** 0 of 544 2025 team-games constant across receivers; minimum sd 1.93 PPR points, median 5.83. Known limit: within-play target-probability sd 0.0165 against population 0.1075, and a play-mean control passes the same check (median sd 5.75), so the model's per-route separation beyond route participation is small.

### Knowledge base updates

- [x] **Record the atom, its first season, and the coverage rule** in [[user:text/league/data-views/measure-contract.md]] and [[████████████████████████-████-███████████-████████]].
