---
title: Repair the JAX home-game possession team for 2001-2015
type: task
status: completed
description: >-
  In all 150 JAX home games from 2001-2015, possession_nfl_team names the wrong team on 96 percent
  of plays and offense_nfl_team copies it. 145 lopsided games enumerated, all JAX home, none after
  2015. Not repairable from the table -- needs an external source.
base_uri: user:task/league/repair-jax-home-game-possession-team.md
created_at: '2026-09-10T23:09:54.129Z'
entity_id: b0dd983a-3144-409c-a188-f5e6506eb48f
finished_at: '2026-09-11T03:31:10.026Z'
observations:
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Medium
public_read: true
tags:
  - user:tag/league-xo-football.md
  - user:tag/software-task.md
updated_at: '2026-09-11T03:31:10.026Z'
visibility_analyzed_at: '2026-11-05T23:50:06.924Z'
---

## Problem

In every Jacksonville HOME game from 2001 through 2015, `nfl_plays.possession_nfl_team` names the wrong team on the overwhelming majority of plays, and `offense_nfl_team` faithfully copies it because enrichment derives offense from possession.

Measured 2026-09-10 against production, 150 games and 24,881 plays with a non-NULL offense: **23,965 of them (96.3%) attribute the offense to the AWAY team.** Confirmed against `play_description` — esbid 2015102500 files 41 Bortles-to-Hurns/Robinson plays as BUF possession, and reads 179 plays BUF-offense against 8 JAX-offense in a game Jacksonville hosted.

**The class was enumerated from the signature, not from the franchise name.** Games where one team holds more than 90% of offensive plays, across 2001-2016: 145 games, and **every single one is a JAX home game**. Zero such games have any other home team, and zero occur in 2016. So the defect is keyed to venue and era, and JAX is the whole class rather than the part someone noticed.

## Why this is a different defect from the swap task

`user:task/league/repair-plays-offense-defense-swap.md` covers rows where `defense_nfl_team = possession_nfl_team`. **These games carry ZERO rows matching that signature** — possession and offense agree with each other and are wrong together, which is exactly why every query comparing the pair is structurally blind to them. Do not merge the two.

It is also why this one is hard: in the swap class the correct value is already in the row. Here it is not. There is no column in `nfl_plays` holding the right answer, so this cannot be repaired from the table and needs an external source.

## What is already ruled out

- **Not a JAC/JAX abbreviation drift.** The 2026-07-25 note on `user:repository/active/league/ABOUT.md` ruled this out on the grounds that possession reads JAX consistently. That premise is WRONG — possession reads BUF — but the conclusion survives for a different reason: the values are a real, wrong franchise, not a spelling variant.
- **Not the home-pinned `defteam` bug.** That one (1,781 rows, 2001 plus esbid 2016090165, tracked on the swap task) corrupts `defense_nfl_team` while leaving offense correct. This corrupts possession at the root.
- **`play_changelog` cannot attribute it.** Zero rows for any of the three team columns across all 4.6M entries.

## Plan

1. **Confirm the class and the boundary.** Reproduce the 145-game/90% enumeration and the 2016 cutoff. The sharp era boundary is the strongest clue available: find what changed in the import path between the 2015 and 2016 seasons.

2. **Identify the writer.** Read the historical NFL play import path for that era. The venue keying is the tell — a home/away inversion at a games-map read would produce exactly this shape. `libs-server/play-enrichment/team-assignment-enrichment.mjs` derives defense from offense and is where an inversion would propagate, but it cannot be the origin, since possession is already wrong before enrichment sees it.

3. **Find a source that can supply correct possession for these games.** This is the gating question and it should be answered before any repair is designed. Before writing the data off as unrecoverable, establish which pipeline WROTE it rather than which vendor the rows describe — a vendor whose window has expired says one door is shut, not that the data is gone. `nfl_play_stats` may independently carry team attribution for these plays and is worth checking first, since it is already local.

4. **Only then design the repair**, and gate it with the operator before applying — this is ~24,000 rows of team attribution.

## Possible related lead

`█████████████████████████████████████████████████████████████████████` (Draft) reports JAX carrying ~24% fewer `player_gamelogs` rows than comparable teams across 2002-2015. Different table and a different source, so it is not obviously the same bug — but two JAX-only defects in overlapping windows is worth one look before treating them as unrelated.

## Verification

- The 90%-lopsided game count goes to zero for 2001-2015 and stays zero for 2016 onward.
- Per-season JAX home-game offense play counts become balanced, matching the 2016-onward shape the same measurement already reads as correct.
- Spot-check repaired rows against `play_description` player identity, which is the only oracle that caught this.
