Fix SR regression header overcounting when exactly one candidate exists - #36061
Conversation
The SR release-readiness tracker rendered 'Regression Candidates — N issues scanned' where N came from $regs.Count. Regression results are hashtables; when Get-RegressionCandidates returns exactly one match, PowerShell unwraps the single-element array on return, so $Data['regressions'] arrives as a lone hashtable and $regs.Count returns its KEY count (13) instead of 1. This produced the live symptom on tracker #35867: 'Regression Candidates — 13 issues scanned' with a single regression candidate. Force array context with @(...) so .Count reflects the candidate count. The N=0 (@() → 0) and N>=2 (real array) paths were already correct; only the N=1 unwrap misfired. The sibling List-based headers and the preview engine are unaffected. Added a discriminating regression test that assigns the result as a scalar hashtable (mimicking the return-unwrap) and asserts the header reports '1 issues scanned', plus an N=2 guard. Verified the test fails pre-fix and passes post-fix. Offline suite 569/0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36061Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36061" |
Skill Validation Results
✅ Skill Validation Results —
|
kubaflo
left a comment
There was a problem hiding this comment.
Note
🤖 This review was automatically generated by a multi-model AI review system (Claude Opus 4.8, GPT-5.5, Gemini 3.1 Pro). Three models independently reviewed the code, then cross-pollinated their findings to reconcile differences. This is Round 1 for a new PR.
Multi-Model Review Summary — PR #36061 Round 1
Title: Fix SR regression header overcounting when exactly one candidate exists
HEAD: 21919a64 · Stats: +44/-1 lines, 2 files
Verdict: ✅ LGTM
Confidence: High (Unanimous 3/3)
Recommendation: Ready to merge. Bug correctly fixed with discriminating tests.
Unanimous Consensus (3/3 Models After Cross-Pollination)
All three models independently analyzed the bug fix and converged to unanimous LGTM with high confidence after cross-pollination.
The Bug
The release-readiness report's regression candidates header was overcounting when exactly one candidate existed:
## Regression Candidates — 13 issues scanned
Root cause: PowerShell array-unwrapping quirk. When Get-RegressionCandidates returns a single-element array with return $results, PowerShell unwraps it to a bare hashtable. Later, $Data['regressions'].Count returns the hashtable's key count (13) instead of the candidate count (1).
Why only exactly one?
- Zero candidates:
$resultsis empty array → stays array →.Count = 0✓ - One candidate:
$resultsis@({hashtable})→ unwraps to{hashtable}→.Count = 13❌ - Multiple candidates:
$resultsstays array →.Count = N✓
The Fix
File: .github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
Line 3460 (was 3461): Changed from:
$candidateCount = $Data['regressions'].CountTo:
# Force array context to avoid PowerShell's single-element array unwrapping
$regs = @($Data['regressions'])
$candidateCount = $regs.CountWhy @() works: Forces array context. Even if $Data['regressions'] is a bare hashtable, @(hashtable) wraps it in a 1-element array → .Count = 1 ✓
Correctness: Minimal, targeted, idiomatic PowerShell pattern. Opus verified all 4 other consumers of $Data['regressions'] are already safe (foreach or @() wrapping).
Tests
New tests (discriminating):
T12— Exactly 1 candidate (regression guard, fails without fix)T13— N=2 candidates (ensures no over-correction)
Opus empirical verification:
- Pre-fix: T12 fails (renders key count instead of 1)
- Post-fix: T12 passes (renders "1 issue")
- T13 passes in both states (N>1 was never broken)
- Suite: 569/0 pass (T8 failure is pre-existing timezone artifact)
CI Validation
GPT's verdict evolution:
- Independent: NEEDS_DISCUSSION (Low) — Cited
gh pr checks --requiredshowing onlymaui-prskip - Cross-poll: Upgraded to LGTM (High) — After learning about
Validate (PR)job
Opus discovery:
release-readiness.ymlValidate (PR) job runs full test suite (2m18s)- Status: ✅ Passing on HEAD
21919a64 - New tests T12/T13 passed in CI
maui-prskip is by-design (.github/**path filter, no product code to build)
Same CI pattern as PR #36031: --required filter hides the functional validation check.
Findings
Zero inline findings after cross-pollination.
Opus initially had a defense-in-depth suggestion (harden root cause at line 2312), but retracted it after verifying that bare accumulator returns are the idiomatic pattern in this file. The consumer-side @() wrap is the standard solution.
Bottom Line
Bug: PowerShell single-element array unwrapping caused hashtable key count (13) to display instead of candidate count (1).
Fix: Force array context with @($Data['regressions']) — correct, minimal, idiomatic.
Tests: Two new tests, empirically verified as discriminating (T12 fails without fix, passes with fix).
CI: Validated via Validate (PR) job passing (569/0 tests).
Verdict: Ship it. 🚀
Confidence: High — Unanimous agreement, empirically verified, CI validated, zero concerns.
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Summary
The SR release-readiness tracker overcounts the regressions header when exactly one regression candidate exists. The live
.NET 10 SR9tracker (#35867) renders:…even though only one issue (#35615) was actually scanned. The summary table, tiers, and verdict all correctly show 1 — only the header is wrong.
Root cause
The header is built from
$regs.Count:Regression results are hashtables.
Get-RegressionCandidatesreturns its$resultsaccumulator, and when exactly one candidate matches, PowerShell unwraps the single-element array on return, so$Data['regressions']arrives as a lone hashtable rather than a 1-element array..Counton a hashtable returns its key count (13 —createdAt, confidence, milestone, state, closedAt, evidence, candidateFixPrs, labels, stateReason, classification, recommendedAction, issue, title), not 1.@()→.Count= 0 ✅ (already correct).Count= 13 ❌ (this bug).Count= element count ✅ (already correct)Fix
Force array context so
.Countalways reflects the candidate count:One line. The sibling SR headers (
$blockingItems,$cleanupItems,$openFixRowsare allList[hashtable]) and the preview engine (Get-PreviewReadiness.ps1, which usesList/@()-wrapped collections) are not affected — this is the only header fed the rawregressionsvalue.Tests
Added a discriminating regression test in
Test-ReleaseReadiness.ps1that reproduces the production unwrap by assigning the regression result as a scalar hashtable (not@(...), which would mask the bug) and asserts the header reports1 issues scanned, plus an N=2 guard for the already-correct path. A precondition assertion locks in that the value is a scalar hashtable so a future edit can't silently neuter the test.ghE2E tests:sr-source-prs.txt, candidate JSON,-InheritFromPriorSrvalidation), reproduced identically on pristinemain(624/3) and unrelated to this change. They pass in CI'srelease-readiness.ymlValidate job, which has a properghtoken.Scope
Separate, focused follow-up off
main— unrelated to the table-escaping fix in #36031 (already merged). No behavior change beyond the header count.