---
title: Close the coaches seed-tier test gap and the fixture-mirror ruling
type: task
status: completed
description: >-
  Exercise the 8-seed name-season tier in import-nfl-coaches.unresolved-rate.spec.mjs (the gap that
  let the fixture go stale) and rule on whether resolve_coach should read every resolution map
  unconditionally or defensively.
base_uri: user:task/league/close-coaches-seed-tier-test-gap.md
created_at: '2026-09-08T19:56:51.593Z'
entity_id: fec887e5-7ba3-4178-8147-14281a8b47be
finished_at: '2026-09-08T19:59:41.415Z'
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Low
public_read: true
relations:
  - relates [[████████████████████-████████████-████-███████████]]
tags:
  - user:tag/league-xo-football.md
  - user:tag/software-task.md
updated_at: '2026-09-08T19:59:41.415Z'
visibility_analyzed_at: '2026-11-06T00:17:41.831Z'
---

# Close the coaches seed-tier test gap and the fixture-mirror ruling

The name-season seed tier added to `scripts/import-nfl-coaches.mjs` in league `4cc76e7e7` (2026-09-08) resolves 8 sourceable 2026 play-callers the coaching reference source does not carry yet. It turned master red because `resolve_coach` reads `resolution.name_season_seed_index` unconditionally while the hand-built spec fixture listed only `seed_index`; `3fa48ec0d` fixed it by adding the map to the fixture. Two loose ends remain, both unowned.

Evidence sits on `██████████████████████████████████████████████████` (status Completed): the `[bug]` and `[finding]` observations dated 2026-09-08. This task is the live home for closing them.

Downstream context: `yarn verify` runs lint, knip and the gate runners but never mocha, so only `yarn test:isolated` or GitHub CI sees a broken spec. Thread `████████████████████████████████████` ("Source DOBs for 10 unresolved 2026 NFL play-callers") is a parked foreground subagent on adjacent work; do not duplicate its sourcing.

## Plan

- [x] Add seed-tier coverage to `test/import-nfl-coaches.unresolved-rate.spec.mjs`: a seeded (name, season) play-caller resolves through `name_season_seed_index` to the seeded `coach_id`, increments `fallback_stats.name_season_seed`, and pushes no `unresolved` entry; build the index from the module's real seed data so the 8 seeded play-callers are asserted, not a hand-made lookalike.
- [x] Mirror the real shape in `run_week`: `fallback_stats` must carry `name_season_seed` so a seed hit cannot throw past it the way the missing map did.
- [x] Decide the design ruling `3fa48ec0d` left open: keep `resolve_coach` dereferencing every `resolution` map unconditionally (a stale fixture fails loudly as a TypeError) versus making it defensive with optional chaining (a stale fixture reads as a clean run that silently skips the tier). Reverse only if the reasons change.
- [x] Prove the spec green and the two drift checks at 0 findings.

## Resolution

Shipped in league `dcdb90d14` on 2026-09-08. The spec now builds the seed index from the real `NEW_PLAY_CALLER_SEEDS` via an exported `build_name_season_seed_index`, and `resolve_coach` is exported for a direct precedence test. Three assertions: all 8 seeds resolve through `process_week` (counter 8, nothing unresolved), each (canonical name, season) key returns its seed `coach_id`, and the tier is consulted only after history-derived lookups miss — the last pinned by giving the history path a different id than the seed for the same (name, season).

The empty-index red-proof fails exactly on the two data-anchored tests (`name_season_seed` stays 0, id resolves null), so the stale-fixture class now fails here instead of passing as a clean shape.

The design ruling was kept as `3fa48ec0d` left it: `resolve_coach` reads every `resolution` map unconditionally. The unconditional read is what made the stale fixture fail loudly as a TypeError; optional chaining would have skipped the tier and read as a clean run — which is the silent-stale-fixture failure the tests now close. A future map added to `build_resolution_map` must be mirrored in the fixture or the data-anchored tests fail, which is the intended contract.

The two drift checks were not re-run: this change is a spec and two module exports with no write to `player` or derived columns, so neither drift check has an input to move.
