---
title: Fix the stale job row that nulls every ████████████████████ signal token field
type: task
status: completed
description: >-
  All 12 ████████████████████ signals ever emitted carry null total_tokens, tool_call_count and
  inference_provider because report_slow_run is handed a job row read before
  record_generation_trajectory writes them. Hoist the values into consts shared by both calls.
base_uri: user:task/league/data-views/fix-stale-job-row-in-slow-generation-signal.md
created_at: '2026-09-10T21:34:45.912Z'
entity_id: 71201928-91ce-40f3-a6eb-969bba062de4
finished_at: '2026-09-10T21:37:10.606Z'
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: High
public_read: true
tags:
  - user:tag/league-xo-football.md
  - user:tag/software-task.md
updated_at: '2026-09-10T22:47:46.035Z'
visibility_analyzed_at: '2026-11-05T23:48:51.729Z'
---

## Problem

Every `████████████████████` signal ever emitted carries `total_tokens=null`, `tool_call_count=null` and `inference_provider=null` — all 12 of them, for the whole life of the signal kind — while the corresponding job rows hold real values. Signal #129437's job row carries 3,004,638 tokens, 30 tool calls, and `vllm-deepseek-v4-flash`.

The field is not missing. `libs-server/data-views/generation/report-slow-generation.mjs:144-150` already reads and emits all three.

The defect is argument freshness in `generation-collector.mjs`:

- `record_generation_trajectory` at `:384-396` computes the three values and WRITES them to the job row.
- `report_slow_run({ job })` at `:403` is handed the `job` object that was read BEFORE that write.

So the reporter reads nulls off a stale in-memory row and faithfully emits them. Nothing is wrong with the emit path; it is being handed a row that predates the write.

## Fix — done in league `cfecd9143`

The three values are hoisted into consts and passed to both `record_generation_trajectory` and `report_slow_run`, rather than re-derived or re-read. That also removed the duplicate `derive_total_tokens(thread)` on the spend path, taking the call count from two to one.

## Verification — done

Red-before-green against the only fixture shape that distinguishes the fix from the bug: a job row whose own `tool_call_count`/`total_tokens`/`inference_provider` are NULL, asserting `report_slow_run` receives the trajectory values anyway. The new case in `test/data-view-generation-collector.spec.mjs` failed with `expected null to equal 12` on the pre-fix code and passes after.

Confirmed live in production as a differing pair: signal #129468, the first slow run after the deploy, carries 26 tool calls, 1,458,668 tokens and `vllm-deepseek-v4-flash`, while pre-fix #129437 and #129235 are null on all three.

## Explicitly out of scope

The bands and the 30s objective. Do not change them.

Measured across 129 non-benchmark runs: p50 53.5s, p95 448.5s, with 106 over 30s, 73 over 45s, 58 over 60s, 32 over 120s, 11 over 300s. The objective is deliberately aspirational — the module says so at `:11-15` — and the bands sit above it on purpose. Twelve signals across all time is not a noise problem.

## Deploy — done 2026-09-10

Shipped with `yarn deploy:all` at `DEPLOY_ACK_RANGE=3`, which satisfied the coupling: the range carried `5d274f4b5` (the emission gate), `9a2f42dac` (an inert `db/` script rename) and this fix together. Built from a throwaway worktree pinned to the sha, because the shared tree was dirty with three other sessions' work.

Production has since moved past it on later sibling deploys; this fix is carried in every one, being an ancestor.
