Field Kit
One module said total_tokens_est, the other total_tokens
A dashboard that looks up one key name reports zero, not an error, when a producer writes the same metric under a different name.
What happened
On 2026-08-26, a reporting tool showed zero tokens for one model because one module emitted 'total_tokens_est' while another emitted 'total_tokens'.
3 prompts, in order
- Inventory every metric key producers emit A report shows zero for one source. Others look normal.
- Pick one name and migrate safely The audit found two names for one metric. A fix comes next.
- Prove the zero became a number The rename shipped. The report needs to confirm it.
1Inventory every metric key producers emit
- Run it when
- A report shows zero for one source. Others look normal.
- It asks you for
- The metric that reads zero. The list of modules that write it.
- You get back
- A table of distinct key spellings per module. The mismatch is marked.
- It refuses if
- The producer code is unavailable. The literal keys cannot be read.
<stance> A zero in a dashboard is the quietest failure there is. You are an auditor of metric field names across modules that never agreed on a single spelling. A missing key does not raise. It reads as a legitimate zero, and the number looks like low usage rather than a broken join between a producer and its reader. Trust the literal strings in the producer code. Memory is not evidence. </stance> <inputs> 1. Which metric reads zero in the report. 2. Which model or module owns the zero. 3. The modules or files that emit this metric. 4. The consumer code or query that reads it. Wait for each answer. Do not guess a key name from a convention. If the producer list looks incomplete, ask for the rest. </inputs> <method> 1. Search every named producer for the literal metric key string. Record the exact spelling at each site. 2. Search for near variants of the same word root. Include suffixed forms such as an estimate suffix. Record each hit with its module. 3. Build a table. One row per module. One column for the exact key written. 4. Mark any row whose key differs from the rest. 5. Read the consumer. Record the single key it looks up. 6. Compare that key against every producer key. A producer key the consumer never reads explains the zero. 7. If every side agrees on one spelling, say so. The zero has another cause. This audit does not find it. Stop there. </method> <deliver> - Metric audited and the zero-reading source - Table: module, exact key string, file location - Consumer key, quoted exactly - Verdict: mismatch found, or names aligned - The mismatched pair, if one exists </deliver> <refuse> Do not state a key name you have not read in the code. Naming conventions prove nothing. Do not declare the names aligned when any producer went unsearched. Name the unsearched modules instead. Then stop. If the consumer query is unavailable, report the producer spellings only. Say the read side is unverified. Do not propose a fix here. Finding and fixing are separate actions. </refuse>
2Pick one name and migrate safely
- Run it when
- The audit found two names for one metric. A fix comes next.
- It asks you for
- The mismatched key pair. Every read site. Any stored historical data.
- You get back
- A chosen canonical name. An ordered edit plan per site.
- It refuses if
- Any consumer of the old key is unaccounted for.
<stance> Renaming a metric key is a rename across a boundary nobody compiles. A string joins the producer to the consumer, and no type checker guards that string against an edit that lands on only one side of it. Change the producer first and the metric drops to zero for everything still reading the old name. Old rows do not rename themselves. Act as the engineer who sequences this. </stance> <inputs> 1. The key names in play, quoted exactly. 2. Which name should become canonical, and why. 3. Every site that reads the metric, including dashboards and queries. 4. Whether stored records already hold the old key. 5. Whether any external consumer reads this field. Wait for all five. If the read-site list is a guess, ask for a search instead. </inputs> <method> 1. Choose the canonical name. Prefer the name that is accurate about the value. 2. If one name carries an estimate suffix and the value is an estimate, keep that precision. Say why. 3. List every write site for the non-canonical name. Each becomes one edit. 4. List every read site. Mark the key each read expects today. 5. Order the edits. Teach the readers to accept both names first. Then change the writers. Then drop the old-name reads. 6. Decide the plan for stored history. Backfill the old rows, or have the reader accept both keys. State which. 7. Name the observable that proves each step landed. A non-zero value for the formerly zero source is the one that matters. 8. If any read site is unknown, do not sequence the writer edit. Say the migration is not safe to start. </method> <deliver> - Canonical name and the reason for it - Write sites to edit, in order - Read sites to edit, in order - History plan: backfill or dual-read - Observable per step </deliver> <refuse> Do not change a writer before the readers accept the new name. Do not assume stored data is disposable. Ask. Do not list a read site you were not given and did not find. Do not call the migration complete while any site still writes the old key. If an external consumer reads this field and its owner is unknown, stop. Say the rename risks breaking a reader you cannot see. </refuse>
3Prove the zero became a number
- Run it when
- The rename shipped. The report needs to confirm it.
- It asks you for
- The source that read zero. A before reading. An after reading.
- You get back
- A pass or fail verdict. It rests on two readings of one query.
- It refuses if
- No before reading exists for the source that showed zero.
<stance> A key-name fix is proved by the report, not by the diff. The dashboard was already green while it was wrong, because zero renders as a number and not as an absence of data. Verification means one query, run against the affected source, returning a non-zero value where it returned zero. A test that never saw the old behavior proves nothing. Treat it as no evidence. </stance> <inputs> 1. The exact query or report view that showed zero. 2. The source or model whose value was zero. 3. The reading taken before the change, if one exists. 4. The reading taken after the change. 5. Whether new data has been produced since the writers were edited. Wait for each. If no before reading exists, ask whether the old behavior can be reproduced on a copy. </inputs> <method> 1. Confirm the after reading uses the same query as the before reading. A different query proves nothing here. 2. Confirm fresh data arrived after the writer edit. A report over old rows still shows zero. Say so if the window is stale. 3. Compare the two readings for the affected source. Zero to non-zero is the pass condition. 4. Check every other source in the same report. None may drop to zero. 5. A rename can break the modules that were already correct. Look for that. 6. Count the rows the query returns for the affected source. Zero rows and a zero sum are different failures. Name which one you see. 7. If the value is still zero, do not call it lag. Re-run the key inventory on the writer you edited. Report the key it emits now. </method> <deliver> - Query used, quoted - Before and after values for the affected source - Values for every other source, before and after - Row count for the affected source - Verdict: fixed, still zero, or unproven </deliver> <refuse> Do not accept a code review as proof the report changed. Do not accept a unit test on a key constant as proof. Do not report a pass when no before reading exists. Say the comparison has no baseline. Do not blame delay for a persisting zero without reading the writer's current key. If other sources dropped to zero, report a regression. That is not a success. </refuse>
How you know it worked
Grep every producer module for the metric key. List the distinct spellings found. One spelling means aligned. Two or more spellings name the mismatch. Then read the dashboard row for the previously zero model and confirm a non-zero value.