Skip to content

Fix SR regression header overcounting when exactly one candidate exists - #36061

Merged
PureWeen merged 1 commit into
mainfrom
pureween/fix-sr-regression-scanned-count
Jun 22, 2026
Merged

Fix SR regression header overcounting when exactly one candidate exists#36061
PureWeen merged 1 commit into
mainfrom
pureween/fix-sr-regression-scanned-count

Conversation

@PureWeen

Copy link
Copy Markdown
Member

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 SR9 tracker (#35867) renders:

## Regression Candidates — 13 issues scanned

…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:

$regs = $Data['regressions']
... "## Regression Candidates — $($regs.Count) issues scanned"

Regression results are hashtables. Get-RegressionCandidates returns its $results accumulator, 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. .Count on a hashtable returns its key count (13 — createdAt, confidence, milestone, state, closedAt, evidence, candidateFixPrs, labels, stateReason, classification, recommendedAction, issue, title), not 1.

  • N = 0@().Count = 0 ✅ (already correct)
  • N = 1 → scalar hashtable → .Count = 13 ❌ (this bug)
  • N ≥ 2 → real array → .Count = element count ✅ (already correct)

Fix

Force array context so .Count always reflects the candidate count:

$regs = @($Data['regressions'])

One line. The sibling SR headers ($blockingItems, $cleanupItems, $openFixRows are all List[hashtable]) and the preview engine (Get-PreviewReadiness.ps1, which uses List/@()-wrapped collections) are not affected — this is the only header fed the raw regressions value.

Tests

Added a discriminating regression test in Test-ReleaseReadiness.ps1 that reproduces the production unwrap by assigning the regression result as a scalar hashtable (not @(...), which would mask the bug) and asserts the header reports 1 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.

  • ✅ Verified the new test fails pre-fix (renders the key count) and passes post-fix.
  • ✅ Offline suite: 569 passed / 0 failed.
  • ℹ️ Full E2E: 627 passed / 3 failed — the 3 failures are pre-existing (live-gh E2E tests: sr-source-prs.txt, candidate JSON, -InheritFromPriorSr validation), reproduced identically on pristine main (624/3) and unrelated to this change. They pass in CI's release-readiness.yml Validate job, which has a proper gh token.

Scope

Separate, focused follow-up off main — unrelated to the table-escaping fix in #36031 (already merged). No behavior change beyond the header count.

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>
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 36061

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 36061"

@github-actions

Copy link
Copy Markdown
Contributor

Skill Validation Results

@PureWeen — new skill validation results are available based on this last commit: 21919a6.
To request a fresh validation after new comments or commits, comment /evaluate-skills.

Overall Passed Static Passed LLM Skipped Skills 20 Agents 6

Skill Validation Results21919a6 · Fix SR regression header overcounting when exactly one candidate exists · 2026-06-22T14:41:17Z

✅ Static Checks Passed

Skills: 20 | Eval specs linted: 7

Full lint output
── .github/skills/agentic-labeler/tests/eval.vally.yaml
npm warn deprecated prebuild-install@7.1.3: No longer maintained. Please contact the author of the relevant native addon; alternatives are available.
✔ .github/skills/agentic-labeler/tests/eval.vally.yaml is valid
── .github/skills/code-review/tests/eval.capability.vally.yaml
✔ .github/skills/code-review/tests/eval.capability.vally.yaml is valid
── .github/skills/code-review/tests/eval.vally.yaml
✔ .github/skills/code-review/tests/eval.vally.yaml is valid
── .github/skills/code-review/tests/hermeticity.vally.yaml
✔ .github/skills/code-review/tests/hermeticity.vally.yaml is valid
── .github/skills/evaluate-pr-tests/tests/eval.vally.yaml
✔ .github/skills/evaluate-pr-tests/tests/eval.vally.yaml is valid
── .github/skills/try-fix/tests/eval.vally.yaml
✔ .github/skills/try-fix/tests/eval.vally.yaml is valid
── .github/skills/verify-tests-fail-without-fix/tests/eval.vally.yaml
✔ .github/skills/verify-tests-fail-without-fix/tests/eval.vally.yaml is valid

⏭️ LLM Evaluation: Skipped

No changed skills with eval specs found.

🔍 Full results and investigation steps

@github-actions github-actions Bot added the area-infrastructure CI, Maestro / Coherency, upstream dependencies/versions label Jun 22, 2026

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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: $results is empty array → stays array → .Count = 0
  • One candidate: $results is @({hashtable}) → unwraps to {hashtable}.Count = 13
  • Multiple candidates: $results stays array → .Count = N

The Fix

File: .github/skills/release-readiness/scripts/Get-ReleaseReadiness.ps1
Line 3460 (was 3461): Changed from:

$candidateCount = $Data['regressions'].Count

To:

# Force array context to avoid PowerShell's single-element array unwrapping
$regs = @($Data['regressions'])
$candidateCount = $regs.Count

Why @() 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 --required showing only maui-pr skip
  • Cross-poll: Upgraded to LGTM (High) — After learning about Validate (PR) job

Opus discovery:

  • release-readiness.yml Validate (PR) job runs full test suite (2m18s)
  • Status: ✅ Passing on HEAD 21919a64
  • New tests T12/T13 passed in CI
  • maui-pr skip 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.

@PureWeen
PureWeen merged commit 83b0333 into main Jun 22, 2026
22 of 23 checks passed
@PureWeen
PureWeen deleted the pureween/fix-sr-regression-scanned-count branch June 22, 2026 20:11
@github-actions github-actions Bot added this to the .NET 10 SR9 milestone Jun 22, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-infrastructure CI, Maestro / Coherency, upstream dependencies/versions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants