Skip to content

fuzz: stop morph passing a run that switched nothing - #758

Merged
deblasis merged 1 commit into
windowsfrom
fuzz/morph-run-floor
Aug 26, 2026
Merged

fuzz: stop morph passing a run that switched nothing#758
deblasis merged 1 commit into
windowsfrom
fuzz/morph-run-floor

Conversation

@deblasis

Copy link
Copy Markdown
Owner

vtabs-morph-fuzz.ps1 could report pass with 0 findings after having toggled nothing. Every term of its oracle is about a switch that went wrong, and all of them are vacuous when no switch happened: with no switch begun the begin/end balance reads 0 -ne 0, the immediate term is gated on $begins, and there are no ghost lines to find. $chordMisses had the same shape - counted, printed, never asserted on.

So gate the run itself. Count the layout chords sent - the startup probe plus one per toggle iteration, excluding the interrupting second chord, which is aimed at a switch still in the air and is meant to be dropped - and require a third of them to have begun a switch with no more than a fifth refused.

Both leave with 1, not 2. A chord the desktop refused, or one the router never saw, is a corpus the harness could not establish rather than a defect in the build, and 1 is the code the runner retries.

The startup probe reads the trace now instead of stat-ing it. A build that ignores WINTTY_MORPH_TRACE and a build whose chord never reaches the router are the same absent file to Test-Path, and only the second is the one that used to run a whole fuzz to a green verdict.

The floor is a third because this harness loses most of what it sends. A healthy run against a clean build converts 38% to 52% of its chords: 13, 14 and 20 of 34, and 16 of 31. The margin over the floor is thin by design.

That loss is a separate defect - morph never arms the XAML island, which #752 fixed in the mouse-fuzz harnesses and skipped here. This change makes it visible, not fixed. Raise the floor once the harness stops losing chords, not before: a build is not at fault for a chord that never reached it.

Two things worth knowing about the thin margin:

  • The conversion rate is environment-dependent, not seed-determined. Seed 1337 produced 13 begins on one run and 20 on another against the same build.
  • So a run that lands under the floor will not replay from -Seed, which is the one property this harness otherwise gives you.

Validation

check result
just fuzz "-Only morph" pass, exit 0 - 34 chords, 0 refused, 20 begins against a floor of 12
just fuzz-selftest SELFTEST OK, exit 0
just fuzz-list exit 0

The new gate expressions were also run directly over the failure cases: all chords refused, chords sent with the router deaf, and near-zero begins all leave with 1; 13/34, 16/31 and 12/34 pass.

The startup probe caught a real case unprompted. Run outside the suite, which minimizes other windows first, Focus() succeeds but the chord reaches nothing - previously a silent green, now exit 1. It also happened under the suite at seed 4242, where the retry cleared it.

Every term of the morph oracle is about a switch that went wrong, and
every one of them is vacuous when no switch happened. With no switch
begun the begin/end balance reads 0 -ne 0, the immediate term is gated
on $begins, and there are no ghost lines to find, so a run where the
layout chord reached nothing left with a green PASS and zero findings.
That is the failure mode #752 was about, and this harness could not see
it.

$chordMisses had the same shape: counted, printed, never asserted on.

So gate the run itself. Count the layout chords sent - the startup probe
plus one per toggle iteration, excluding the interrupting second chord,
which is aimed at a switch still in the air and is meant to be dropped -
and require a third of them to have begun a switch, with no more than a
fifth refused outright.

Both leave with 1, not 2. A chord the desktop refused, or one the router
never saw, is a corpus this harness could not establish rather than a
defect in the build, and 1 is the code the runner retries.

The startup probe reads the trace now instead of stat-ing it. A build
that ignores WINTTY_MORPH_TRACE and a build whose chord never reaches
the router are the same absent file to Test-Path, and only the second is
the one that used to run a whole fuzz to a green verdict.

The floor is a third rather than something tighter because this harness
loses most of what it sends: a healthy run against a clean build
converts 38% to 52% of its chords, measured at 13, 14 and 20 of 34 and
at 16 of 31. The margin over the floor is thin by design. Raise it once
the harness stops losing chords, not before - a build is not at fault
for a chord that never reached it.
@deblasis
deblasis merged commit 58a7f14 into windows Aug 26, 2026
111 checks passed
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