Over one morning on a game project I watched three tracker rows get overturned by their own first measurement. Not “the fix was harder than expected” — the cause written in the row was wrong, three times, in a batch of work that was otherwise going fine. That rate is not bad luck. It is a structural feature of how bug reports become tickets.
Here is the shape. Someone plays the game and says something true and vague: her face goes blackish sometimes. Someone else — often me, an hour later, tidying notes into a plan — writes a row. The row needs a “what it is” column, because a row with an empty cause column looks unfinished. So a mechanism gets written down. And the moment it is written down in the tracker’s flat declarative voice, it stops reading like a guess and starts reading like a finding.
The next person to pick up that row does not re-derive it. They implement it.
Three rows, three wrong causes
“Her face turns blackish, so there must be a bad frame.” The row said: one corrupted generated frame, audit each frame, regenerate the bad one. The measurement said every frame was clean — skin lightness 67–82, hair colour difference under 3. The real cause was sampling. A 461-pixel figure was being drawn at 68 pixels through a bilinear filter with no mipmaps, so a four-tap sample of a 6.8-texel footprint was effectively point-sampling the dark ink lines, and which speck of ink survived moved from frame to frame. Byte-identical captures settled it: mipmaps alone changed nothing, a mipmapping filter alone changed nothing, both together fixed all fifteen frames.
Note how plausible the row was. “One bad frame” explains an intermittent artefact perfectly. It is just not what was happening.
“The character sits too low on the platform.” The row blamed the player’s
anchor point, because an anchor bug had genuinely been fixed a week earlier in
the same area. The measurement said the player was never wrong — her drawn feet
were one pixel from her collider. The platforms were 63 pixels low, on every
multi-cell chunk, because the alignment script converted art rows with a formula
that only holds for one-cell tiles. And the script’s own --check mode used the
same formula, so it cheerfully reported 0 of 31 chunks misaligned. The
verification was wrong in exactly the way the code was wrong.
“He looks like he has a double chin.” The row said: the model’s bare neck shows as a pale strip above the beard; carry the beard down the nape. The measurement said the front seam already had beard on both sides. The bare nape was the back of the head, under hair, where no camera ever points. The actual defect was a 6 mm bridge of flat pale texels with a sharp outline shelf at its top edge — and it was bit-identical between the two model versions, which is precisely why the colour fix that shipped between them had not touched it.
Two more from the same week fit the pattern: a “spawn point floating over nothing” was a stale camera attached to a second body, and a fishing rod “pointing at the ground” was a bone’s live pose, not its rest pose.
Why the diagnosis is so often wrong, and so rarely doubted
Three things stack up.
The transcriber has to write something. A plausible mechanism is the most useful-looking thing to put in the cause column, and an honest “unknown” looks like laziness in a review.
The tracker’s voice is declarative. Tickets do not have a grammatical mood for “I suspect”. A hypothesis rendered in that voice is indistinguishable from a finding to every subsequent reader, including the person who wrote it.
And — this is the one that got me three times in a morning — the wrong diagnosis is usually adjacent to a real recent fix. The anchor row borrowed the credibility of last week’s anchor fix. The bad-frame row borrowed the credibility of a real frame-generation bug. A wrong cause that sits next to a right one inherits its evidence.
The shape of the fix
It is procedural and it is cheap. The first act on any row is to measure the symptom, not to implement the diagnosis.
Concretely, four things:
Write the symptom in the reporter’s own words, in its own field, and mark the
cause column with a prefix that cannot be misread — hypothesis: or
probably:. Two extra characters buy a whole grammatical mood the tracker
didn’t have.
Brief whoever picks the row up to build the instrument first. Ten minutes with a screenshot script, a rasterised silhouette, a colour histogram — and either the row is confirmed and you proceed with confidence, or you have saved the hour the wrong fix would have cost. In three of the cases above the instrument changed the fix entirely, which no amount of careful implementation of the wrong cause would have done.
Keep the instrument. The measurement scripts written for those three rows now answer the next five rows in the same area from a number instead of an impression. An instrument is a capital asset; a fix is a consumable.
And when the diagnosis turns out wrong, correct the row, not just the code. A doc that still carries the refuted mechanism will mislead the next reader, and it will do so with the same declarative confidence that misled the last one.
There’s a corollary in the second story worth carrying separately: the
alignment script’s --check derived its expectation from the same broken
formula as the thing it was checking, so it could not disagree. A verification
that shares a premise with the code is not a verification. But that is its own
post.
The rule: measure the symptom before you implement the cause — the row’s diagnosis is the first guess, not the finding.
sources: concepts/a-ledgers-diagnosis-is-a-hypothesis, with a nod to
concepts/a-hard-coded-floor-is-a-hard-coded-subject