Skip to content

Fix iOS infinite layout invalidation loop from bit-exact Frame equality (#35142)#35144

Closed
Qythyx wants to merge 1 commit intodotnet:mainfrom
Qythyx:fix/ios-layout-loop-frame-equality-35142
Closed

Fix iOS infinite layout invalidation loop from bit-exact Frame equality (#35142)#35144
Qythyx wants to merge 1 commit intodotnet:mainfrom
Qythyx:fix/ios-layout-loop-frame-equality-35142

Conversation

@Qythyx
Copy link
Copy Markdown

@Qythyx Qythyx commented Apr 27, 2026

Description of Change

VisualElement.Frame's setter uses Rect's bit-exact equality (Rect.Equals on doubles) to decide whether to enter UpdateBoundsComponents. On iOS, ULP-level non-determinism from UILabel.SizeThatFits / CoreText propagates through VerticalStackLayout accumulation and Grid(\"*\",\"Auto\") star-row arithmetic into a child's Frame, producing a Rect that differs from the cached one by ~10–22 ULP.

Bit-exact equality treats those rects as different, fires Width/Height PropertyChanged + SizeChanged, layout invalidates, UIKit reschedules layoutSubviews, and the cycle repeats without converging. The UI thread becomes permanently stuck.

This change adds Rect.EqualsApproximately(other, epsilon) (non-breaking, no change to Rect.Equals / ==) and uses it in the Frame setter with epsilon = 1e-9 — well above ~10⁻¹³ ULP at typical layout magnitudes and well below sub-pixel resolution on any current iOS device (a 3× display's pixel is ~0.333pt). It mirrors the precedent set by SafeAreaPadding.EqualsAtPixelLevel, introduced for issues #32586 and #33934 to fix the analogous infinite-layout-cycle problem on the safe-area path.

Captured per-cycle pattern from the repro (G17 precision)

```text
*** PROPCHG border Height=556.00000063578295
*** SIZECHG border 390x556.00000063578295
*** PROPCHG vstack Y=566.00000063578295
*** PROPCHG vstack Height=149.99999936421713
*** SIZECHG vstack 370x149.99999936421713

*** PROPCHG border Height=556.00000063578273
*** SIZECHG border 390x556.00000063578273
*** PROPCHG vstack Y=566.00000063578273
*** PROPCHG vstack Height=149.99999936421725
*** SIZECHG vstack 370x149.99999936421725
```

The two heights toggle indefinitely (~22 ULP for the border, ~12 ULP for the vstack) and never converge.

Issues Fixed

Fixes #35142

Tests

Two new test files exercise both the loop trigger and the new helper:

  • VisualElementTests.FrameAssignmentIgnoresSubPixelDifferences — uses the actual border heights captured in the repro trace (556.00000063578295 vs 556.00000063578273). On unmodified `main` the test fails (`SizeChanged` fires after the second `Frame` assignment); after the fix it passes.
  • `RectTests` — focused coverage of `Rect.EqualsApproximately` (identical, ULP-different, beyond-epsilon, half-epsilon).

Local results on macOS / .NET 10:

  • Controls.Core.UnitTests: 5544 passed, 30 pre-existing skipped, 0 failed
  • Core.UnitTests: 806 passed, 3 pre-existing skipped, 0 failed
  • Graphics.Tests: 376 passed, 0 failed (4 new `RectTests` included)

End-to-end verification

A minimal MauiReactor repro (`Grid(",Auto", "", Border, VerticalStackLayout-of-labels)`) reliably froze the UI thread on iPhone 16e simulator within ~1 second. With the fix, the same repro renders and stays responsive — no `PROPCHG` flood, no freeze.

VisualElement.Frame's setter uses Rect's bit-exact equality (Rect.Equals
on doubles) to decide whether to enter UpdateBoundsComponents. On iOS,
ULP-level non-determinism from UILabel.SizeThatFits / CoreText
propagates through VerticalStackLayout accumulation and Grid("*","Auto")
star-row arithmetic into a child's Frame, producing a Rect that differs
from the cached one by ~10-22 ULP. Bit-exact equality treats the rects
as different, fires Width/Height PropertyChanged + SizeChanged, layout
invalidates, UIKit reschedules layoutSubviews, and the cycle repeats
without converging. The UI thread becomes permanently stuck.

Add Rect.EqualsApproximately(other, epsilon) and use it in the Frame
setter with epsilon = 1e-9 - well above ~10^-13 ULP at typical layout
magnitudes and well below sub-pixel resolution on any current iOS
device. Mirrors the precedent set by SafeAreaPadding.EqualsAtPixelLevel
(introduced for issues dotnet#32586 and dotnet#33934).

Adds two test files:
- VisualElementTests.FrameAssignmentIgnoresSubPixelDifferences:
  Regression test using the actual border heights captured in the repro
  trace (556.00000063578295 vs 556.00000063578273); fails on
  pre-fix main, passes after the change.
- RectTests: focused coverage of Rect.EqualsApproximately.

Fixes dotnet#35142
@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 -- 35144

Or

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

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label Apr 27, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@Qythyx! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Apr 27, 2026

🤖 AI Summary

👋 @Qythyx — new AI review results are available. Please review the latest session below.

📊 Review Sessioncd1ec75 · Fix iOS infinite layout invalidation loop from bit-exact Frame equality · 2026-04-27 15:59 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: IOS · Base: main · Merge base: 388b82f1

Test Without Fix (expect FAIL) With Fix (expect PASS)
🧪 RectTests RectTests ✅ FAIL — 9s ✅ PASS — 5s
🧪 VisualElementTests VisualElementTests ✅ FAIL — 28s ✅ PASS — 22s
🔴 Without fix — 🧪 RectTests: FAIL ✅ · 9s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 743 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/samples/GraphicsTester.Portable/GraphicsTester.Portable.csproj (in 892 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Text.Markdig/Graphics.Text.Markdig.csproj (in 892 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj (in 1.63 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics.Skia/Graphics.Skia.csproj (in 1.81 sec).
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics.Skia -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics.Skia/Debug/net10.0/Microsoft.Maui.Graphics.Skia.dll
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/netstandard2.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics.Text.Markdig -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics.Text.Markdig/Debug/netstandard2.0/Microsoft.Maui.Graphics.Text.Markdig.dll
  GraphicsTester.Portable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/GraphicsTester.Portable/Debug/net10.0/GraphicsTester.Portable.dll
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(11,21): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(23,18): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(32,22): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(33,22): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(34,22): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(35,22): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/RectTests.cs(44,21): error CS1061: 'Rect' does not contain a definition for 'EqualsApproximately' and no accessible extension method 'EqualsApproximately' accepting a first argument of type 'Rect' could be found (are you missing a using directive or an assembly reference?) [/Users/cloudtest/vss/_work/1/s/src/Graphics/tests/Graphics.Tests/Graphics.Tests.csproj]

🟢 With fix — 🧪 RectTests: PASS ✅ · 5s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics.Skia -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics.Skia/Debug/net10.0/Microsoft.Maui.Graphics.Skia.dll
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/netstandard2.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics.Text.Markdig -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics.Text.Markdig/Debug/netstandard2.0/Microsoft.Maui.Graphics.Text.Markdig.dll
  GraphicsTester.Portable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/GraphicsTester.Portable/Debug/net10.0/GraphicsTester.Portable.dll
  Graphics.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics.Tests/Debug/net10.0/Graphics.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics.Tests/Debug/net10.0/Graphics.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.04]   Discovering: Graphics.Tests
[xUnit.net 00:00:00.10]   Discovered:  Graphics.Tests
[xUnit.net 00:00:00.10]   Starting:    Graphics.Tests
[xUnit.net 00:00:00.13]   Finished:    Graphics.Tests
  Passed Microsoft.Maui.Graphics.Tests.RectTests.EqualsApproximatelyTreatsHalfEpsilonDifferenceAsEqual [4 ms]
  Passed Microsoft.Maui.Graphics.Tests.RectTests.EqualsApproximatelyReturnsTrueForIdenticalRects [< 1 ms]
  Passed Microsoft.Maui.Graphics.Tests.RectTests.EqualsApproximatelyAbsorbsUlpDifferences [< 1 ms]
  Passed Microsoft.Maui.Graphics.Tests.RectTests.EqualsApproximatelyReturnsFalseWhenAnyComponentExceedsEpsilon [< 1 ms]

Test Run Successful.
Total tests: 4
     Passed: 4
 Total time: 0.4644 Seconds

🔴 Without fix — 🧪 VisualElementTests: FAIL ✅ · 28s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/TestUtils/TestUtils.csproj (in 399 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/Core.UnitTests/Controls.Core.UnitTests.csproj (in 4.65 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 4.72 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 5.05 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 5.05 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/maps/src/Maps.csproj (in 5.05 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 5.05 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 5.07 sec).
  2 of 10 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
  TestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
  Controls.Core.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.10]   Discovering: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:00.67]   Discovered:  Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:00.68]   Starting:    Microsoft.Maui.Controls.Core.UnitTests
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.RadialGradientBrush), defaultCtor: True) [24 ms]
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.ImmutableBrush), defaultCtor: False) [10 ms]
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.SolidColorBrush), defaultCtor: False) [9 ms]
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.LinearGradientBrush), defaultCtor: True) [9 ms]
  Passed HandlerDoesPropagateWidthChangesWhenUpdatedDuringSizedChanged [34 ms]
  Passed If HeightRequest has been set and is reset to -1, the Core Height should return to being Unset [2 ms]
  Passed ShadowDoesNotLeak [34 ms]
  Passed RectangleGeometrySubscribed [9 ms]
  Passed BindingContextPropagatesToBackground [2 ms]
[xUnit.net 00:00:00.91]     FrameAssignmentIgnoresSubPixelDifferences [FAIL]
[xUnit.net 00:00:00.91]       Assert.Equal() Failure: Values differ
[xUnit.net 00:00:00.91]       Expected: 0
[xUnit.net 00:00:00.91]       Actual:   1
[xUnit.net 00:00:00.91]       Stack Trace:
[xUnit.net 00:00:00.91]         /_/src/Controls/tests/Core.UnitTests/VisualElementTests.cs(345,0): at Microsoft.Maui.Controls.Core.UnitTests.VisualElementTests.FrameAssignmentIgnoresSubPixelDifferences()
[xUnit.net 00:00:00.91]            at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:00.91]            at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
  Passed WidthAndHeightRequestPropagateToHandler [1 ms]
  Passed GradientBrushSubscribed [11 ms]
  Passed ShadowSubscribed [9 ms]
  Passed HandlerDoesntPropagateWidthChangesDuringBatchUpdates [< 1 ms]
  Passed If WidthRequest has been set and is reset to -1, the Core Width should return to being Unset [< 1 ms]
  Passed FocusedElementGetsFocusedVisualState [2 ms]
  Failed FrameAssignmentIgnoresSubPixelDifferences [1 ms]
  Error Message:
   Assert.Equal() Failure: Values differ
Expected: 0
Actual:   1
  Stack Trace:
     at Microsoft.Maui.Controls.Core.UnitTests.VisualElementTests.FrameAssignmentIgnoresSubPixelDifferences() in /_/src/Controls/tests/Core.UnitTests/VisualElementTests.cs:line 345
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
  Passed ClipDoesNotLeak(type: typeof(Microsoft.Maui.Controls.Shapes.RectangleGeometry)) [10 ms]
  Passed ClipDoesNotLeak(type: typeof(Microsoft.Maui.Controls.Shapes.EllipseGeometry)) [13 ms]
[xUnit.net 00:00:00.91]   Finished:    Microsoft.Maui.Controls.Core.UnitTests
  Passed ContainerChangedFiresWhenMapContainerIsCalled [1 ms]

Test Run Failed.
Total tests: 19
     Passed: 18
     Failed: 1
 Total time: 1.1726 Seconds

🟢 With fix — 🧪 VisualElementTests: PASS ✅ · 22s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13944879
  Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
  Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
  TestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
  Controls.Core.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.07]   Discovering: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:00.58]   Discovered:  Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:00.59]   Starting:    Microsoft.Maui.Controls.Core.UnitTests
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.RadialGradientBrush), defaultCtor: True) [20 ms]
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.ImmutableBrush), defaultCtor: False) [7 ms]
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.SolidColorBrush), defaultCtor: False) [7 ms]
  Passed BackgroundDoesNotLeak(type: typeof(Microsoft.Maui.Controls.LinearGradientBrush), defaultCtor: True) [6 ms]
  Passed HandlerDoesPropagateWidthChangesWhenUpdatedDuringSizedChanged [30 ms]
  Passed If HeightRequest has been set and is reset to -1, the Core Height should return to being Unset [3 ms]
  Passed ShadowDoesNotLeak [44 ms]
  Passed RectangleGeometrySubscribed [8 ms]
  Passed BindingContextPropagatesToBackground [2 ms]
  Passed WidthAndHeightRequestPropagateToHandler [1 ms]
  Passed GradientBrushSubscribed [10 ms]
  Passed ShadowSubscribed [9 ms]
  Passed HandlerDoesntPropagateWidthChangesDuringBatchUpdates [< 1 ms]
  Passed If WidthRequest has been set and is reset to -1, the Core Width should return to being Unset [< 1 ms]
  Passed FocusedElementGetsFocusedVisualState [3 ms]
  Passed FrameAssignmentIgnoresSubPixelDifferences [< 1 ms]
  Passed ClipDoesNotLeak(type: typeof(Microsoft.Maui.Controls.Shapes.RectangleGeometry)) [17 ms]
  Passed ClipDoesNotLeak(type: typeof(Microsoft.Maui.Controls.Shapes.EllipseGeometry)) [9 ms]
[xUnit.net 00:00:00.80]   Finished:    Microsoft.Maui.Controls.Core.UnitTests
  Passed ContainerChangedFiresWhenMapContainerIsCalled [< 1 ms]

Test Run Successful.
Total tests: 19
     Passed: 19
 Total time: 1.0981 Seconds

📁 Fix files reverted (4 files)
  • src/Controls/src/Core/VisualElement/VisualElement.cs
  • src/Graphics/src/Graphics/PublicAPI/net/PublicAPI.Unshipped.txt
  • src/Graphics/src/Graphics/PublicAPI/netstandard/PublicAPI.Unshipped.txt
  • src/Graphics/src/Graphics/Rect.cs

🧪 UI Tests — Category Detection

No UI test categories detected for this PR.


🔍 Pre-Flight — Context & Validation

Issue: #35142 - [iOS] Grid("*,Auto") over VerticalStackLayout enters non-converging measurement 2-cycle on iPhone 16e
PR: #35144 - Fix iOS infinite layout invalidation loop from bit-exact Frame equality (#35142)
Platforms Affected: iOS (confirmed; does not reproduce on iPhone 17 Pro with wider screen)
Files Changed: 3 implementation, 3 test

Key Findings

  • The root cause is bit-exact Rect equality in VisualElement.Frame setter — ULP-level floating-point differences from iOS UILabel.SizeThatFits propagate through VerticalStackLayoutGrid("*,Auto") star-row arithmetic, producing a 2-cycle that never converges
  • The fix adds Rect.EqualsApproximately(other, epsilon) with epsilon=1e-9 (well above ULP drift ~10⁻¹³, well below sub-pixel resolution ~0.333pt on 3× displays)
  • The PR is community contribution from the issue reporter (same person), showing deep analysis
  • Precedent established by SafeAreaPadding.EqualsAtPixelLevel (issues Layout issue using TranslateToAsync causes infinite property changed cycle on iOS #32586, [iOS] TranslateToAsync causes spurious SizeChanged events after animation completion, triggering infinite layout loops #33934) for the same class of problem
  • Gate: ✅ PASSED — both RectTests and VisualElementTests fail on main, pass with fix
  • UpdateBoundsComponents is called only from Frame.set — the redundant bit-exact inner guard at line 1840 is now effectively unreachable but harmless

Code Review Summary

Verdict: LGTM
Confidence: high
Errors: 0 | Warnings: 0 | Suggestions: 3

Key code review findings:

  • 💡 UpdateBoundsComponents (line 1840) has a now-unreachable _frame == bounds guard — dead code, harmless but misleading
  • 💡 EqualsApproximately public API has no documented/enforced precondition for epsilon >= 0 (negative epsilon silently makes all comparisons false)
  • 💡 RectTests.cs missing exact-boundary test case (diff == epsilon should return true per <= semantics)

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #35144 Add Rect.EqualsApproximately(epsilon=1e-9) and use it in VisualElement.Frame setter instead of bit-exact equality ✅ PASSED (Gate) Rect.cs, VisualElement.cs, PublicAPI files + tests Original PR

Impacted UI Test Categories

Layout — Grid layout measurement/convergence is directly affected


🔬 Code Review — Deep Analysis

Code Review — PR #35144

Independent Assessment

What this changes:
Rect gains a new public method EqualsApproximately(Rect other, double epsilon) that compares each component with Math.Abs(a - b) <= epsilon. The VisualElement.Frame setter's existing bit-exact equality guard (_frame == value) is replaced with _frame.EqualsApproximately(value, 1e-9). Two test files are added: RectTests.cs (focused on the new method) and a new test case in VisualElementTests.cs (using real values from a repro trace). Both PublicAPI.Unshipped.txt files are updated correctly.

Inferred motivation:
iOS CoreText / UILabel.SizeThatFits produces values that differ from one layout pass to the next by ~10–22 ULP (order of magnitude ~1e-12). Because Rect == is bit-exact, these "same" rectangles are treated as different, firing Width/Height PropertyChanged and SizeChanged → layout invalidation → UIKit reschedules layoutSubviews → cycle never converges. The fix absorbs these ULP-level differences so no spurious events fire.


Reconciliation with PR Narrative

Author claims: ULP-level non-determinism from UILabel.SizeThatFits feeds through VerticalStackLayout/Grid("*","Auto") arithmetic into a child's Frame, creating a non-converging 2-cycle. Fix mirrors SafeAreaPadding.EqualsAtPixelLevel precedent from issues #32586 and #33934.

Agreement: Root-cause analysis matches. The SafeAreaPadding.EqualsAtPixelLevel comparison is apt. Note that EqualsAtPixelLevel is dynamic (reads UIScreen.MainScreen.Scale at call time), while EqualsApproximately uses a static absolute epsilon — a deliberate simplification since Rect lives in Microsoft.Maui.Graphics (cross-platform, no UIKit). ✅ Correct tradeoff.


Findings

💡 Suggestion — Dead exact-equality guard inside UpdateBoundsComponents

Location: src/Controls/src/Core/VisualElement/VisualElement.cs:1840

void UpdateBoundsComponents(Rect bounds)
{
    if (_frame == bounds)  // ← now unreachable dead code
        return;

UpdateBoundsComponents has exactly one caller: the Frame setter. The setter's EqualsApproximately check is a strict superset of exact equality — if _frame == value were true, EqualsApproximately would have already returned early. This guard can never be true in practice. Not a bug (dead code is harmless here), but misleading. Consider removing it or replacing with Debug.Assert(_frame != bounds).

💡 Suggestion — EqualsApproximately lacks epsilon precondition (public API)

Location: src/Graphics/src/Graphics/Rect.cs:87

A negative epsilon silently causes all comparisons to return false (since Math.Abs(x) >= 0 > epsilon always). The method is public API. Adding either a <param> doc note (Must be non-negative) or an ArgumentOutOfRangeException guard for epsilon < 0 would make the contract explicit.

💡 Suggestion — Test coverage gap at exact epsilon boundary

Location: src/Graphics/tests/Graphics.Tests/RectTests.cs

The tests verify 0.5 * epsilon returns true and 2 * epsilon returns false, but the exact-boundary case (diff == epsilon) is untested. Since the implementation uses <=, that case should return true. Adding one assertion like:

Assert.True(rect.EqualsApproximately(new Rect(0, 0, 100, 100 + epsilon), epsilon));

would nail down the contract at the boundary.


Blast Radius

Scope: VisualElement.Frame setter in Microsoft.Maui.Controls.Core. Every view in MAUI goes through this setter during layout. The change only affects the early-return condition — it widens what is considered "equal" from exact to approximate. On non-iOS platforms (Android/Windows), frame values are typically pixel-aligned and will never produce sub-1e-9 ULP noise, so the behavior is identical. On iOS the change suppresses spurious layout cycles. No other call sites for UpdateBoundsComponents exist.

Failure mode probes:

  • Could epsilon suppress real frame updates? 1e-9 pt is sub-nanometer. No layout engine produces intentional deltas that small. Not a real concern.
  • Cross-platform safety? Windows/Android produce pixel-aligned values. Safe.
  • Negative epsilon edge case? API misuse would silently fail; already noted in suggestions above.

Verdict

LGTM (confidence: high)

The fix is correct, precisely scoped, and directly mirrors established MAUI precedent (SafeAreaPadding.EqualsAtPixelLevel). The epsilon value of 1e-9 is safe on all platforms. The new Rect.EqualsApproximately method is a clean general-purpose addition with minimal, well-documented public API surface. Three minor suggestions above, none blocking merge.

Errors: 0 | Warnings: 0 | Suggestions: 3


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix (claude-opus-4.6) Round-to-Canonical in UpdateBoundsComponents — snap frame components with Math.Round(value, 10) before storing, eliminating ULP noise at source; keeps bit-exact Frame comparison ✅ PASS VisualElement.cs only No new public API; normalization vs. tolerance strategy
2 try-fix (claude-sonnet-4.6) Sticky Width/Height Coercion in UpdateBoundsComponents — preserve current Width/Height value if ` new-current < 1e-9`; X/Y updated at full precision ✅ PASS
3 try-fix (gpt-5.3-codex) Coerce Width/Height near-equality in bindable property coerce layer — ULP-scale deltas keep current value instead of propagating change notifications ✅ PASS VisualElement.cs, Rect.cs, PublicAPI files Targets event source (W/H change) not frame comparison
4 try-fix (gpt-5.4, gemini unavailable) Quantize entire Frame to 0.001pt grid before compare/store — collapses ULP noise to deterministic discrete state ✅ PASS VisualElement.cs, Rect.cs, PublicAPI files Grid quantization is 1,000,000× coarser than PR's epsilon
PR PR #35144 Add Rect.EqualsApproximately(epsilon=1e-9) public method; use in Frame setter instead of bit-exact equality ✅ PASSED (Gate) Rect.cs, VisualElement.cs, PublicAPI files Original PR — new general-purpose API, mirrors SafeAreaPadding precedent

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 No NO NEW IDEAS

Exhausted: Yes

Selected Fix: PR's fix — Reason:


📋 Report — Final Recommendation

✅ Final Recommendation: APPROVE

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #35142 root-cause confirmed; 3 impl files, 3 test files classified
Code Review LGTM (high) 0 errors, 0 warnings, 3 suggestions (all non-blocking)
Gate ✅ PASSED iOS — RectTests & VisualElementTests fail without fix, pass with fix
Try-Fix ✅ COMPLETE 4 attempts, 4 passing; PR's fix selected as best
Report ✅ COMPLETE

Code Review Impact on Try-Fix

Code review found no errors or warnings — only 3 minor suggestions (dead code guard, epsilon precondition doc, boundary test gap). None influenced the fix approach itself. The LGTM verdict with high confidence confirmed the PR's design is sound, so Try-Fix models were directed to explore genuinely different architectural layers (normalization, sticky coercion, bindable layer, quantization) rather than variations on the same approach. All 4 alternatives passed the regression tests, validating that multiple fix strategies are viable — but the PR's approach remains the clearest and most reusable.

Summary

PR #35144 fixes an iOS-specific infinite layout loop caused by ULP-level non-determinism in UILabel.SizeThatFits propagating through MAUI's layout pipeline into VisualElement.Frame. The fix adds Rect.EqualsApproximately(epsilon) and uses it in the Frame setter to absorb sub-pixel floating-point noise before firing PropertyChanged/SizeChanged events. The fix is correct, well-tested, well-documented, and follows established MAUI precedent (SafeAreaPadding.EqualsAtPixelLevel).

Root Cause

On iOS, UILabel.SizeThatFits returns ULP-non-deterministic values (~1e-12 variation) across consecutive layout passes. This variation propagates through VerticalStackLayout accumulation and Grid("*","Auto") star-row arithmetic, reaching a child element's Frame setter with values differing by ~10–22 ULP (~1e-12). The Frame setter's bit-exact equality (_frame == value) treats these as different, fires Width/Height PropertyChanged + SizeChanged → layout invalidates → UIKit reschedules layoutSubviews → the 2-cycle repeats indefinitely.

Fix Quality

The fix is high quality:

  • Epsilon choice (1e-9) is correctly calibrated: orders of magnitude above the observed ULP noise (~1e-12) and orders of magnitude below sub-pixel resolution (~0.333pt on 3× displays). No real layout updates will be suppressed.
  • Scope: Rect.EqualsApproximately is added as a new non-breaking public method; Rect.Equals/== are unchanged. The Frame setter change is a one-line replacement of an equality check.
  • Architecture: Fix is at the correct layer (Frame setter gate), preventing spurious UpdateBoundsComponents entry entirely.
  • Tests: Two test files — RectTests.cs (4 focused tests of the new method) and VisualElementTests.FrameAssignmentIgnoresSubPixelDifferences (using actual repro trace values) — provide strong coverage.
  • Three minor suggestions from code review: (1) remove now-dead if (_frame == bounds) guard in UpdateBoundsComponents; (2) add epsilon precondition doc/guard to EqualsApproximately; (3) add exact-boundary test case (diff == epsilon). None are blocking.

@MauiBot MauiBot added s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Apr 27, 2026
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 27, 2026

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

PureWeen added a commit that referenced this pull request Apr 27, 2026
Agents didn't know what to do when no CI builds existed (common for
community PRs) or when devicetests/uitests weren't triggered. Added
note about /azp run commands and explicit pipeline triggers.

Discovered via multi-agent testing against PRs #35144 and #35150.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 27, 2026

/review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Expert Code Review completed successfully!

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Expert Code Review — PR #35144

Methodology: 3 independent reviewers with adversarial consensus (findings only included when ≥2/3 agree; disputed 1/3 findings verified via targeted follow-up).


Summary

The core fix — replacing bit-exact Rect equality with epsilon-based approximate comparison in the VisualElement.Frame setter — is sound, well-motivated, and consistent with existing MAUI patterns (mirrors SafeAreaPadding.EqualsAtPixelLevel). The epsilon value (1e-9) is well-justified: ~330 million times smaller than a Retina pixel, yet large enough to absorb the ~22 ULP non-determinism observed in the iOS layout trace.

Tests are thorough, covering identical rects, ULP-level differences from the actual repro trace, per-component boundary violations, and the Frame setter's event suppression behavior.


Findings

# Severity File Finding Consensus
1 🔴 CRITICAL PublicAPI.Unshipped.txt (platform TFMs) Missing EqualsApproximately entry in 6 platform-specific PublicAPI files — CI will fail with RS0016 3/3 reviewers (after follow-up)
2 🟡 MODERATE VisualElement.cs UpdateBoundsComponents internal bit-exact guard is now dead code — maintenance trap for future callers 2/3 reviewers
3 🟢 MINOR Rect.cs EqualsApproximately NaN semantics diverge from Equals (NaN components → always false) — should be documented 2/3 reviewers
4 🟢 MINOR Rect.cs No validation on epsilon parameter — negative/NaN epsilon silently returns false for all inputs 2/3 reviewers

Discarded findings (1/3 only, not confirmed by follow-up): cross-platform epsilon comment suggestion, missing boundary test suggestion.


Blocking Issue

Finding #1 is the only blocker. The 6 platform-specific PublicAPI.Unshipped.txt files under src/Graphics/src/Graphics/PublicAPI/ (net-ios, net-android, net-maccatalyst, net-windows, net-tizen, net-macos) need the same entry added:

Microsoft.Maui.Graphics.Rect.EqualsApproximately(Microsoft.Maui.Graphics.Rect other, double epsilon) -> bool

Non-Blocking Suggestions

Findings #2#4 are documentation/comment improvements that can be addressed in this PR or follow-up:

  • Add a comment in UpdateBoundsComponents noting the Frame setter is the sole caller
  • Add <remarks> to EqualsApproximately documenting NaN behavior and epsilon requirements

Test Coverage Assessment

Good coverage. The PR includes:

  • RectTests.cs — 4 tests covering the new EqualsApproximately API (identity, ULP absorption, per-component rejection, half-epsilon boundary)
  • VisualElementTests.cs — Regression test using actual values from the iOS repro trace, verifying no spurious SizeChanged/PropertyChanged events

No device/UI tests are included, but the fix is in shared cross-platform code testable via unit tests, which is appropriate.

Note

🔒 Integrity filter blocked 2 items

The following items were blocked because they don't meet the GitHub integrity level.

  • #35144 pull_request_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
  • #35144 pull_request_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Expert Code Review for issue #35144 · ● 14M

@@ -1 +1,2 @@
#nullable enable
Microsoft.Maui.Graphics.Rect.EqualsApproximately(Microsoft.Maui.Graphics.Rect other, double epsilon) -> bool
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.

🔴 CRITICAL — Missing PublicAPI entries for platform-specific TFMs (3/3 reviewers)

Rect.EqualsApproximately is defined in shared Rect.cs and compiles for all TFMs. This PR adds the entry to net/ and netstandard/ only, but PublicAPI.targets resolves platform TFMs (e.g., net10.0-ios) to platform-specific directories (net-ios/PublicAPI.Unshipped.txt, etc.). CI runs in Validate mode and will emit RS0016 for every platform build.

Fix: Add Microsoft.Maui.Graphics.Rect.EqualsApproximately(Microsoft.Maui.Graphics.Rect other, double epsilon) -> bool to all 6 platform-specific PublicAPI.Unshipped.txt files:

  • net-ios
  • net-android
  • net-maccatalyst
  • net-windows
  • net-tizen
  • net-macos

/// </summary>
/// <param name="other">The rectangle to compare against.</param>
/// <param name="epsilon">The maximum absolute difference, per component, that is treated as equal.</param>
public bool EqualsApproximately(Rect other, double epsilon)
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.

🟢 MINOR — NaN semantics diverge from Rect.Equals (2/3 reviewers)

Equals(Rect) uses double.Equals(double) which returns true for NaN.Equals(NaN). In contrast, EqualsApproximately uses Math.Abs(X - other.X) <= epsilon, where NaN - NaN = NaN and NaN <= epsilon = false. So a NaN-component rect compares equal to itself with Equals but not with EqualsApproximately.

In the Frame setter context: if a platform produced a NaN frame, the old code would no-op (dedup), but the new code would call UpdateBoundsComponents and fire events on every pass.

Not a practical risk (NaN frames indicate an upstream bug), but worth documenting.

Suggestion: Add a <remarks> to the XML doc: "Unlike Equals, this method returns false when any component is NaN."

set
{
if (_frame == value)
if (_frame.EqualsApproximately(value, FrameEqualityEpsilon))
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.

🟡 MODERATE — UpdateBoundsComponents internal guard is now dead code (2/3 reviewers)

UpdateBoundsComponents (called on line 1895) has an internal if (_frame == bounds) return; bit-exact guard. With this PR, the Frame setter now exits early for any difference ≤ 1e-9, so UpdateBoundsComponents is only called when the difference exceeds the epsilon — making the internal bit-exact check guaranteed false (dead code).

This isn't a correctness bug today (confirmed UpdateBoundsComponents is only called from the Frame setter), but it's a maintenance trap: a future caller bypassing the Frame setter would re-expose the original oscillation.

Suggestion: Add a brief comment inside UpdateBoundsComponents noting that the Frame setter is the sole caller and the primary deduplication path is the approximate check above.

/// <param name="epsilon">The maximum absolute difference, per component, that is treated as equal.</param>
public bool EqualsApproximately(Rect other, double epsilon)
{
return Math.Abs(X - other.X) <= epsilon
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.

🟢 MINOR — No epsilon validation on public API (2/3 reviewers)

epsilon is an unrestricted double parameter. A negative epsilon makes Math.Abs(...) <= epsilon always false (since Math.Abs ≥ 0), so the method silently returns false for all inputs — including identical rects. A NaN epsilon has the same effect.

The internal caller uses a hardcoded const 1e-9 (safe), but this is a new public API surface.

Suggestion: Either add an ArgumentOutOfRangeException guard for epsilon < 0, or (more likely preferred on a struct hot-path) document the requirement: "epsilon must be non-negative; a negative value causes the method to always return false."

@Qythyx
Copy link
Copy Markdown
Author

Qythyx commented Apr 28, 2026

Note, 10.0.51 fixes this, so my fix is probably not necessary. I had actually updated to .51 a while ago, but it introduced new bugs around SafeAreaInsets so I had reverted back to .41. Then I found this bug and spent a few days debugging and reproing it without trying to see if .51 fixed it.

@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 28, 2026

Alright! @Qythyx Thanks for letting me know <3

@kubaflo kubaflo closed this Apr 28, 2026
PureWeen added a commit that referenced this pull request Apr 28, 2026
- Community PR: replaced PR #35144 (got closed during eval) with
  PR #34710 (older, stable state). Reworded rubric to not assume
  'community PR' — tests the general 'no builds' detection.
- Removed non-activation scenarios: 'general query' baseline was
  already 5/5 (no room to improve), 'code review' timed out at
  120s. These dragged the improvement score negative. The skill's
  boundary is CI-vs-not-CI which is better tested by prompt routing
  than eval scenarios.
- Kept 3 positive scenarios that showed real improvement (+1.0 and
  +2.3 in the first eval run).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] Grid("*,Auto") over VerticalStackLayout enters non-converging measurement 2-cycle on iPhone 16e

3 participants