---
title: Declare the hand-read data-view column params
type: task
status: planned
description: >-
  Give a declaration to the data-view column params that a column definition reads by hand out of
  params in its own query builder, so the generation catalog sees them and the resolver param-KEY
  check can ship. Measured: 43 of 55 residual rejections across 189 saved views are these
  undeclared-but-working keys.
base_uri: user:task/league/data-views/declare-hand-read-column-params.md
created_at: '2026-08-28T05:12:22.996Z'
entity_id: 28be80b3-5453-4e19-a680-a06368e1ca5b
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Medium
public_read: true
relations:
  - relates [[user:task/league/data-views/reach-full-column-param-vocabulary.md]]
tags:
  - user:tag/league-xo-football.md
updated_at: '2026-09-11T16:23:08.262Z'
visibility_analyzed_at: '2026-11-05T23:48:46.564Z'
---

# Implementation Plan: Declare the hand-read data-view column params

## Overview

- Give a declaration to the data-view column params that a column definition reads by hand out of `params` inside its own query builder, so the generation catalog can see them and the resolver's param-KEY check can finally ship.
- Impact: the check is the only thing that would catch a generated view naming a param that does not exist. Without it a fabricated param key reaches the query builder and is silently ignored, and the user cannot tell "the model answered your question" from "the model invented a filter that was dropped on the way to the screen".
- Ordering: depends on nothing. Unblocks the last open step of [[user:task/league/data-views/reach-full-column-param-vocabulary.md]].

## Background

`reach-full-column-param-vocabulary` took catalog param coverage from 56 of 597 columns to 440 by reading the client field registry and each column's `consumes_params_extra`. It then measured the param-KEY check across all 189 production saved views and left it OUT: 55 rejections across 11 views, of which **43 are real params the query builder actively honours and no registry declares**.

Those 43 are a third param source. `consumes_params_extra` was folded in specifically to test whether these keys were merely inherited; coverage rose 413 to 440 and the residual did not move at all, which is what establishes they are hand-read rather than inherited.

The known members, with their uses across the corpus:

| Param | Uses | Read by |
| --- | --- | --- |
| `scoring_format_id` | 20 | `player-projected-column-definitions.mjs`, several plays columns |
| `sourceid` | 17 | `player-projected-column-definitions.mjs`, which states outright the persisted key deliberately did not move |
| `platform_source_id` | 7 | `player-dfs-ownership-column-definitions.mjs` |
| `output_column_params`, `output_match_column_params` | 6 | written by `data-views-saved-view-migration.mjs` itself |

### Assumptions

- The list above is what the 189-view corpus exercises, not necessarily every hand-read param. A grep of `params.` reads inside `libs-server/data-views-column-definitions/` is the way to find the rest, and it should be run rather than assumed.
- `sourceid` must keep its spelling. `player-projected-column-definitions.mjs` says the persisted key deliberately did not move when the rest renamed to `source_id`; renaming it now silently drops the filter on every saved view carrying it.
- `output_column_params` and `output_match_column_params` are structural sibling-column references, not filter params. They may belong in a separate carve-out rather than the param registry.

## Design

The end state is one source per param: a column that accepts a key declares it, and the query builder reads what was declared. No new registry format is introduced if an existing one fits.

- **Knowledge Base Impact.** `docs/data-views-system.md` already names this third source in its "Where the generation catalog's param vocabulary comes from" subsection; that passage gets updated to say it is closed. Tag: `user:tag/league-xo-football.md`.
- **Working tier.** None.

## Plan

- [ ] **Enumerate every hand-read param**
  - Sweep `libs-server/data-views-column-definitions/` for reads off `params` that resolve to no declaration in the column's own `column_params`, its `consumes_params_extra`, or the shared registries.
  - Verify: the enumeration reproduces at least the five keys above, and the count is stated rather than described.

- [ ] **Declare them where the column already declares its params**
  - Prefer extending each column's existing `column_params` over inventing a new field, so the catalog picks them up with no builder change.
  - Verify: `build_data_view_generation_catalog()` reports a higher `columns_with_param_keys` than 440, counted.

- [ ] **Restore the resolver param-KEY check**
  - File: `libs-server/data-views/generation/resolve-generated-table-state.mjs`, whose header carries the full measurement and the reason the check is out.
  - Verify: re-run across all 189 production saved views, post-`migrate_table_state`, over catalog-known columns. Require near-zero false positives with every surviving rejection adjudicated as a real defect. If it does not clear, the check stays out and the new measurement replaces the old one in the header — do not ship it at a material false-positive rate.

## Testing & Validation

- [ ] **Ratchet the coverage number**
  - Verify: `test/data-views.generation-catalog-param-coverage.spec.mjs` raises `MINIMUM_COLUMNS_WITH_PARAM_KEYS` above 430 to the newly measured floor, and the suite is collected by `yarn check:test-collection`.

- [ ] **Prove the restored check can go red**
  - Verify: a spec feeds a `table_state` carrying a fabricated param key and asserts the resolver reports it, alongside a control view that must pass untouched.

- [ ] **Confirm the bundle still builds**
  - Verify: `yarn build` exits 0 and the data-views page still renders columns with params through the editor.
