Put the Metric's Scope in Its Headline, Not in Its Script
An automated watcher reported "new bugs in sprint: 0" for the third day running. A Highest-priority bug had been raised three hours earlier, on a story outside the tracked set.
"New bugs in sprint: 0." Third day running.
Three hours before that message went out, someone raised a Highest-priority bug.
The Query Was Right
That is the part that decides how you have to think about this.
The bug hung off a story outside the tracked sprint set. The watcher asks for new bugs linked to the stories it tracks, the bug was not linked to one of them, so it was not returned. Every step is correct. Run the query by hand and you get the same zero.
Nothing malfunctioned. No integration dropped a record, no field was misconfigured, no filter was left over from last quarter. The report was accurate about the question it asked and misleading about the question it appeared to answer, and there is no error log anywhere that would ever show that.
Which means the usual instincts are useless here. You cannot monitor for it, you cannot alert on it, and reviewing the query will confirm the query.
Scope Lives in the Script Because That Is Where It Is Cheap
Every automated number has a boundary. It has to — a query without a population is not a query.
The boundary gets chosen for practical reasons at the moment the thing is built. A tracked set of stories exists already. Sprint membership is messy, cross-project links are messy, and a defined list is the version that runs fast and returns something today. That is a reasonable engineering decision and I would probably make it too.
Then the output has to be phrased. And the phrasing that comes out is "new bugs in sprint," because that is what the author was thinking about, not "new bugs linked to the stories in the tracked set."
The constraint that made the query cheap is invisible in the sentence the reader sees. The scope is in the script. Nobody reads the script. Everybody reads the sentence, every morning.
From there it only degrades. A metric is named for what it measures and read as what people wish it measured, and the wish is always broader than the measurement. Nobody ever hopes their bug watcher is covering less than it says.
A Quiet Inbox Is the Most Expensive Kind of Wrong
Now add the value.
If the report had said "new bugs in sprint: 7" and only five of them were real, someone would have opened it. Wrong numbers get investigated because they invite a click. A number that looks off is a prompt.
Zero is not a prompt. Zero is permission to move on.
And zero repeated is worse than zero once. Three days of nothing does not read as three data points. It reads as a state — the sprint is quiet, testing is not finding much, we are in good shape — and the reader stops treating the message as a measurement at all. It becomes weather.
That is the specific danger of a scoped metric that reports absence. An automated report that fires teaches you to look. An automated report that stays silent teaches you to stop. By day three the watcher has trained its own audience out of the habit that would have caught it.
Meanwhile the highest-severity item on the board is three hours old and has never appeared anywhere.
Write the Boundary Into the Sentence
The rule is small and slightly awkward, which is why it does not happen on its own.
Whatever population a number is computed over goes in the headline, next to the number, every time it is published. Not in the wiki page about the dashboard. Not in a tooltip. In the sentence.
"New bugs on the tracked stories: 0." That is two extra words and it fixes the entire failure mode, because it tells the reader what the zero does not cover at the exact moment they read the zero.
- Name the boundary in the shortest true form you can find. "On the tracked stories," "in this project only," "excluding sub-tasks," "raised since 09:00." If you cannot say the boundary in six words, that is worth knowing too — it usually means the scope is more arbitrary than anyone realised.
- Repeat it on every publication, including the quiet ones. The scope caveat is needed most on the days the number is boring, which is precisely when the temptation to shorten the message is strongest.
There is a second benefit that shows up later. A stated boundary is a thing people can argue with. Someone reads "the tracked stories," realises their story is not one of them, and says so — and that conversation is impossible while the label says "in sprint," because "in sprint" sounds like it already includes everything.
Assume It Will Be Quoted
The reason to take this seriously is not the report. It is the second life the number has after the report.
A number with an undocumented boundary eventually gets quoted as a statement about the whole project. It travels into a status update, then into a slide, then into a sentence somebody says to a stakeholder: no new bugs for three days. Every step strips context, and the boundary was never attached in the first place, so there is nothing to strip — the number arrives at the top of the organisation carrying a claim far larger than the query ever made.
You cannot control that journey. You can control what is welded to the number before it starts.
So treat your own automated reports as artefacts under test. Read the message as a stranger would, ask what population a reasonable person would assume it covers, then compare that to the population in the script. Where the two differ, the difference is a defect in the report, and it is yours to fix — even though nothing is broken and every result is correct.
The last automated quality number you sent: what does it not cover, and does the person reading it know that?