Spun out of #1837, which asked for a low-key qualifier for "N consecutive zero-item cycles on a target that HAS user databases". #1837 shipped the part that needs no new signal; this is the part that does.
What #1837 shipped. The Collection Health reads (Lite, the Darling Viewer, and the MCP DarlingDataReader) gained two columns computed from the same collection_log aggregate the grid already ran:
MAX(CASE WHEN status NOT IN ('ERROR', 'PERMISSIONS') THEN error_message END) AS last_note,
COUNT(CASE WHEN status NOT IN ('ERROR', 'PERMISSIONS') THEN error_message END) AS note_count
CollectorHealthClassifier.FormatCollectionNote renders them as "<note> (all 96 runs)" when note_count covers the whole window and "<note> (3 of 96 runs)" otherwise. "all N runs" is the persistently-empty signal, and it is a window-total rather than a true consecutive streak — with only two possible note texts in practice that reads the same, and it costs no ordering pass.
What is still missing. The qualifier cannot yet distinguish
- a target that is legitimately empty (no user databases, no AGs, nothing matching the collector's filter) — must stay quiet, and stays HEALTHY today, from
- a target that has user databases and is still enumerating zero of them — the interesting case, e.g. a login that cannot enter any of them.
Answering that at health-read time needs a per-server user-database count (or AG count, per collector) available to the health query. The candidate source is the database_config collector's table, which makes the health read a cross-collector join, and raises questions #1837 deliberately did not answer: what the count means when database_config itself has not run or is stale; which collector's enumeration maps to which inventory (query_store -> databases with Query Store on, ag_replica_states -> AGs, index_object_stats -> databases post-filter); and whether the answer belongs in the health SQL or is computed collector-side at enumeration time (where the target's database count is already in hand and could ride the same probe-failure/note channel).
Constraints inherited from #1837, non-negotiable: the band ORDER and semantics must not change; a legitimately-empty target must keep reading HEALTHY; this stays informational, never a new error band.
Pinned by EmptyEnumerationNoteTests / DarlingEmptyEnumerationNoteTests (The_Note_Never_Reaches_The_Banding) in both apps — any implementation here has to keep those green.
Spun out of #1837, which asked for a low-key qualifier for "N consecutive zero-item cycles on a target that HAS user databases". #1837 shipped the part that needs no new signal; this is the part that does.
What #1837 shipped. The Collection Health reads (Lite, the Darling Viewer, and the MCP
DarlingDataReader) gained two columns computed from the samecollection_logaggregate the grid already ran:CollectorHealthClassifier.FormatCollectionNoterenders them as"<note> (all 96 runs)"whennote_countcovers the whole window and"<note> (3 of 96 runs)"otherwise. "all N runs" is the persistently-empty signal, and it is a window-total rather than a true consecutive streak — with only two possible note texts in practice that reads the same, and it costs no ordering pass.What is still missing. The qualifier cannot yet distinguish
Answering that at health-read time needs a per-server user-database count (or AG count, per collector) available to the health query. The candidate source is the
database_configcollector's table, which makes the health read a cross-collector join, and raises questions #1837 deliberately did not answer: what the count means whendatabase_configitself has not run or is stale; which collector's enumeration maps to which inventory (query_store-> databases with Query Store on,ag_replica_states-> AGs,index_object_stats-> databases post-filter); and whether the answer belongs in the health SQL or is computed collector-side at enumeration time (where the target's database count is already in hand and could ride the same probe-failure/note channel).Constraints inherited from #1837, non-negotiable: the band ORDER and semantics must not change; a legitimately-empty target must keep reading HEALTHY; this stays informational, never a new error band.
Pinned by
EmptyEnumerationNoteTests/DarlingEmptyEnumerationNoteTests(The_Note_Never_Reaches_The_Banding) in both apps — any implementation here has to keep those green.