Skip to content

ObservedHours states what its zero-coverage fallback defends and pins it: the nominal window, never a near-zero divisor, moot behind the collectors' unobserved guard (#3538 A7 follow-through from #3616 review) - #3623

Merged
erikdarlingdata merged 1 commit into
devfrom
fix/3538-observed-hours-zero-coverage
Sep 18, 2026
Merged

erikdarlingdata merged 1 commit into
devfrom
fix/3538-observed-hours-zero-coverage

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

The zero-coverage fallback in ObservedHours says what it is for, and is pinned

Follow-through on #3616's third review round: the reviewer's non-blocking inline note asked that the coverage_fraction == 0 arm of FactScorer.ObservedHours either be documented as the 0/0 defence it is, or reconsidered. #3616 auto-merged at 0e1a7f75 seconds before the commit carrying the answer pushed, so that commit is cherry-picked here unchanged; the inline reply on #3616 names it.

What the arm does and why. A coverage_fraction of exactly 0 is what WindowCoverage.Unobserved stamps. Both collectors (DuckDbFactCollector.Waits.cs, PgFactCollector.Waits.cs) emit no wait fact when ObservedDurationMs <= 0, so a fact carrying zero coverage and a non-zero wait_time_ms is a fact no shipped collector produces — the arm defends the arithmetic against 0/0 and should be moot. It deliberately falls back to the nominal window rather than to a near-zero divisor: dividing by ~0 would turn any trace on such a fact into an enormous hourly rate and fire on the artifact, whereas the nominal reading is the pre-#3538 form — the least-sensitive honest one. The doc comment now says so.

Pinned, so the choice cannot silently flip: Score_PerHourGates_ReadZeroCoverageAsTheNominalWindow_NotAsNearZero — 12,000 ms of PAGELATCH_UP over a nominal 4 h with coverage_fraction = 0 reads as 3 s/hr → 0. Executed against the built PerformanceMonitor.Analysis.dll before pinning (0, as expected); the xunit test first runs in CI.

What it does NOT do

Nothing else — two files, 22 added lines, no behaviour change (the arm's result is unchanged; it is now documented and pinned).

Partial for #3538 (A7 follow-through). Builds: PerformanceMonitor.Analysis, Lite.Tests — 0 warnings, 0 errors.

Which component(s) does this affect?

  • Lite
  • Darling
  • Lite Tests
  • Darling Tests
  • SQL collection scripts
  • Documentation
  • Full Dashboard (deprecated) — via the shared scorer; no Dashboard file changed
  • CLI Installer (deprecated)

How was this tested?

Compile-verified; the pinned value executed against the built shared library; xunit execution is CI's.

Checklist

  • I have read the contributing guide
  • My code builds with zero warnings (dotnet build -c Debug)
  • I have tested my changes against at least one SQL Server version — comment + pin only; no server surface touched
  • I have not introduced any hardcoded credentials or server names

…window, not a near-zero divisor, and moot behind the collectors' unobserved guard (review note on #3616)
@erikdarlingdata
erikdarlingdata enabled auto-merge (squash) September 18, 2026 18:05
@claude

claude Bot commented Sep 18, 2026

Copy link
Copy Markdown

Reviewed. This is a comment+test-only change (confirmed via diff — no logic lines touched in FactScorer.cs, only /// doc comment added). Verified:

  • The doc comment's claim that "both collectors emit no wait fact at all when ObservedDurationMs <= 0" checks out against Lite/Analysis/DuckDbFactCollector.Waits.cs:164/235/302 and Darling/PerformanceMonitor.Darling.Analysis/PgFactCollector.Waits.cs:194/261/321 — both guard identically, so Lite/Darling stay in parity here.
  • The new pinned test's math is correct: 12,000 ms / 4h nominal (coverage_fraction=0 falls back to nominal per FactScorer.cs ObservedHours) = 3,000 ms/hr, under the 10,000 ms/hr PagelatchUpMinWaitMsPerObservedHour threshold → 0.0, matching the assertion.

No correctness, security, or parity issues found.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — verified this is comment+test-only (no logic change in FactScorer.cs), confirmed the doc comment's claim about both collectors' zero-coverage guard against the actual Waits.cs files in Lite and Darling, and checked the new pinned test's arithmetic against the threshold constant.

@erikdarlingdata
erikdarlingdata merged commit 710c5f3 into dev Sep 18, 2026
8 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/3538-observed-hours-zero-coverage branch September 18, 2026 18:18
erikdarlingdata added a commit that referenced this pull request Sep 19, 2026
…spliced once

Fifty-nine PRs merged to dev today across the coordinator's lanes and the wave-2
worker's; each lane returned its entry to a buffer instead of touching this file,
so that fifty-plus PRs did not each rebase the same twenty lines. This is the one
splice. Every entry is one line (the archiver's compact() and the pins read them
that way); riders fold into their parent's entry (#3599 under #3590, #3619 under
#3611, #3623 under #3616, #3640 under #3633; #3617 test-only and #3661 re-cut as
#3666 carry none); #3657's entry is in because it MERGED to dev - the twin to main
is what is still pending.

[Unreleased] gains a `### Added` above `### Fixed` (Keep-a-Changelog order) for the
six new capabilities: per-user theme colours (#3606 / #3577 arm B), routed alert
families (#3668 / #3598), the PostgreSQL logging audit tool (#3643 / #3607), the
service-side wait sampler (#3645 / #3604), and the log-event classifier with its
temp-file / autovacuum parser families (#3646 / #3601, #3664 / #3602 #3603). The
other forty-eight are honesty fixes to existing surfaces and append to `### Fixed`
after the wave-1 bullets, in PR-number order.

Thirty-six reference definitions added for the issues the new entries cite and the
index did not yet define; the [Unreleased] group is one ascending run again, which
moves [#3557] into its slot (the one deleted line). Nothing under ## [3.8.0] or
older is touched; the archive script was not run. One editorial touch: the #3585
entry ended in a dangling "Darling" and now reads "Darling only." (the tool exists
only in the Darling MCP host).

tools/changelog/changelog_archive.py verify: all PASS (1420 bold entries, floor
1,329; 1,358 distinct refs resolve; CRLF throughout; 356,539 bytes under the
750 KiB ceiling). ChangelogIndexAndArchiveTests: 5/5 pass via a net10.0 harness.
erikdarlingdata added a commit that referenced this pull request Sep 19, 2026
…spliced once (#3672)

Fifty-nine PRs merged to dev today across the coordinator's lanes and the wave-2
worker's; each lane returned its entry to a buffer instead of touching this file,
so that fifty-plus PRs did not each rebase the same twenty lines. This is the one
splice. Every entry is one line (the archiver's compact() and the pins read them
that way); riders fold into their parent's entry (#3599 under #3590, #3619 under
#3611, #3623 under #3616, #3640 under #3633; #3617 test-only and #3661 re-cut as
#3666 carry none); #3657's entry is in because it MERGED to dev - the twin to main
is what is still pending.

[Unreleased] gains a `### Added` above `### Fixed` (Keep-a-Changelog order) for the
six new capabilities: per-user theme colours (#3606 / #3577 arm B), routed alert
families (#3668 / #3598), the PostgreSQL logging audit tool (#3643 / #3607), the
service-side wait sampler (#3645 / #3604), and the log-event classifier with its
temp-file / autovacuum parser families (#3646 / #3601, #3664 / #3602 #3603). The
other forty-eight are honesty fixes to existing surfaces and append to `### Fixed`
after the wave-1 bullets, in PR-number order.

Thirty-six reference definitions added for the issues the new entries cite and the
index did not yet define; the [Unreleased] group is one ascending run again, which
moves [#3557] into its slot (the one deleted line). Nothing under ## [3.8.0] or
older is touched; the archive script was not run. One editorial touch: the #3585
entry ended in a dangling "Darling" and now reads "Darling only." (the tool exists
only in the Darling MCP host).

tools/changelog/changelog_archive.py verify: all PASS (1420 bold entries, floor
1,329; 1,358 distinct refs resolve; CRLF throughout; 356,539 bytes under the
750 KiB ceiling). ChangelogIndexAndArchiveTests: 5/5 pass via a net10.0 harness.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant