---
title: Reconcile the NFL classification vocabularies
type: task
status: completed
description: >-
  Fix the vocabulary defects the taxonomy research found: the two meanings of within_window, the
  duplicated miss-mechanism list, three coverage vocabularies with contradictory rows, two
  quarterback-decision vocabularies and the duplicate film box count.
base_uri: user:task/league/reconcile-nfl-classification-vocabularies.md
created_at: '2026-10-20T01:11:48.810Z'
entity_id: 111f0559-5562-4b24-a5bd-37c88463ae8d
finished_at: '2026-10-20T03:43:58.445Z'
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Medium
public_read: true
relations:
  - subtask_of [[█████████████-██████████████-████-████-███-█████-███-██████████████-███████████]]
  - blocked_by [[user:task/league/build-nfl-classification-registry.md]]
  - relates [[█████████████████████-██████████-███████████-███-████████-█████████████]]
started_at: '2026-10-20T02:52:09.255Z'
tags:
  - user:tag/league-xo-football.md
updated_at: '2026-10-20T03:46:50.629Z'
visibility_analyzed_at: '2026-11-05T23:49:56.096Z'
---

# Implementation Plan: Reconcile the NFL classification vocabularies

## Overview

- Fix every vocabulary defect the taxonomy research found so each concept has one name across league code, Python tools and the knowledge base.
- Impact: queries, graders and judgments stop disagreeing on spelling and meaning.
- Ordering: after [[user:task/league/build-nfl-classification-registry.md]]; coordinate the coverage items with [[█████████████████████-██████████-███████████-███-████████-█████████████]], which owns the collapsed `man_zone` view column.

## Background (defects found 2026-10-19)

- `within_window` means a miss mechanism in `classify-selection-outcome.mjs:37` and a window reading in the team-game classifier; the knowledge base spells the mechanism `within-range`.
- `MISS_MECHANISMS` is declared in JavaScript and again in `cli/nfl/file-miss-mechanism-judgments.py:33`; `reconcile-verdict-store.py` reuses `unmeasured` as a grading result.
- Coverage has three vocabularies: film `coverage_family` and `coverage_shell`, charting `coverage_class` and `coverage_type`. Observed 2025 REG pass plays carry contradictory pairs (ZONE with COVER_1 72, MAN with COVER_3 23, ZONE with COVER_2_MAN 23, ZONE with COVER_0 8; query: `select coverage_class, coverage_type, count(*) from nfl_plays where season_year=2025 and season_type='REG' and play_type='PASS' group by 1,2`).
- Quarterback decision: film `checkdown`/`scramble` against `read_thrown_type` `CHECKDOWN`/`SCRAMBLE_DRILL`.
- Film `box_defenders` duplicates the `nfl_plays.box_defenders` column family.
- The `miss_mechanism_judgment` store has no classifier-version column.

### Assumptions

- Renaming the miss mechanism needs a data migration on stored judgments (unchecked; count rows carrying `within_window` before renaming).

## Design

- Charting vocabulary wins for coverage: `coverage_type` is the charted class; family and shell are registry values derived from type. Contradictory class-and-type rows are flagged by source, not rewritten.
- The miss mechanism takes `within_range` (the knowledge base's word); `within_window` stays the window reading only.
- Python reads mechanisms from the registry export.
- Judgments carry the registry version they were judged against.
- Knowledge Base Impact: [[user:text/nfl/nfl-betting/method/betting-outcome-grading.md]] mapping table; [[█████████████████-████-█████████-███████████]].

## Plan

- [x] **Rename the mechanism to `within_range`** in league code, the judgment store and stored rows. `miss_mechanism` is registry version 2; the production CHECK moved by private adhoc `2026-10-20-rename-within-window-miss-mechanism.sql`. No stored row held `within_window` in either store, so the migration moved zero rows.
- [x] **One mechanism list**: `cli/nfl/nfl_classification_registry.py` reads the registry export; `file-miss-mechanism-judgments.py` and `reconcile-verdict-store.py` take their mechanisms from it, the latter now spelling `team_volume` and `within_range`. The grading result with no comparable value is `ungraded`, apart from the `unmeasured` mechanism.
- [x] **Judgment registry version column** `miss_mechanism_registry_version`, set on every row by the filing CLI. Declared optional because base cannot add a required column to an existing table. A filed test row carried 2 and was deleted.
- [x] **Coverage mapping.** Registry entries `coverage_type`, `coverage_class` and `read_thrown` bind the stored enums, so the vocabulary gate covers them. A value may carry `corresponding_values`: each charted coverage type names the film family and shell it implies. `read_coverage_contradiction` flags a class against its type's family; `scripts/report-coverage-class-contradictions.mjs` counts by season and source. 2025 REG pass plays hold 145 contradictions, matching the baseline query: 139 pair the primary charter's class with the secondary charter's type, 6 are the primary charter against itself. 2024 and 2026 hold none. The data-views coverage task's coverage item had already landed, so nothing there needed coordinating.
- [x] **Quarterback decision**: `downfield` maps to `FIRST`/`SECOND`, `checkdown` to `CHECKDOWN`, `scramble` to `SCRAMBLE_DRILL`; `throwaway` and `sack` have no read thrown. `SCRAMBLE_DRILL` covers both scramble runs (963 2025 REG rush rows) and throws on the move (1,325 pass rows).
- [x] **Retire the film `box_defenders` label** and the `count` value kind. Production held zero film observations, so no stored row was affected.
- [x] **Knowledge base**: grading doc spells the mechanisms as the registry does, with the retired spellings in its mapping table; judgment database doc; coverage contradiction note in the charted-columns query-trap sheet; taxonomy reference regenerated.

Landed in league `1ef286a30` and user-base `2ea6e6d341`.
