Skip to content

The unmasked-wrapper rule quotes a reconverge test that no longer exists #17

Description

@vyncint

Today — the prediction model quotes a reconverge test that reconverge has
deleted, so the lab reports the analyzer's correct answers as conformance
violations.

crates/simt-diff/src/model.rs:89:

const UNMASKED_WRAPPER: &str = "dialect simt.rs test `unmasked_wrappers_are_the_documented_v1_gap`: \
    warp::shuffle, warp::ballot, warp::all/any and the reduce_* helpers hide an \
    implicit full mask inside cuda-device and are not analyzed in v1";

and the rule that rests on it, model.rs:452:

// The wrapper hides its mask inside cuda-device, so nothing about the call
// site matters: it is not analyzed at all in v1.
if mask == Mask::ImplicitWrapper {
    return quoted(ExpectedStatic::Silent, "collective_via_unmasked_wrapper",);
}

That test no longer exists in reconverge. grep at 0.4.0 finds nothing for
unmasked_wrappers_are_the_documented_v1_gap; what is there instead is
crates/reconverge-dialect-oxide/src/simt.rs:416
unmasked_wrappers_carry_an_implicit_full_mask — the opposite claim. And
reconverge's README now documents the wrappers as covered:

plus the unmasked convenience wrappers (warp::shuffle, warp::ballot,
all, any, popc, the reduce_* helpers) … warp::ballot(x) under
divergence is treated exactly like warp::ballot_sync(0xffff_ffff, x).

What it costs

simt-diff conformance --mutants against crates.io 0.4.0, on this host:

66 VIOLATION of 147 cases
  14  collective_via_unmasked_wrapper      <- this rule

Every one of the 14 reads predicted silence, got RC002/Confirmed. And the
analyzer is right every time. Taking one at random:

$ simt-diff mutate --source collective_unmasked_wrapper+wrap_in_loop@0
//! ORACLE: KnownMaskInvalid, computed by executing every thread of block=32 --
//! the collective at collective@0.0.0 runs with 8 lane(s) present while its
//! mask names 32 lane(s), so the named set and the participating set are not
//! the same

warp::ballot(true) with 8 of 32 lanes present. RC002/Confirmed is the correct
answer. The lab calls it a violation.

That is the one failure a differential lab cannot afford: it is currently
evidence against an analyzer that got something right, and if anyone trusts
the violation count as a quality signal it points the wrong way.

Fix

Mask::ImplicitWrapper should predict what reconverge actually does — treat it
as Mask::Literal(0xffff_ffff), which is precisely the semantics its README
states — and the rule at model.rs:452 should go, so the wrapper cases fall
through to the ordinary convergence rules.

Two other places carry the same stale quote and want the same treatment:

  • crates/simt-diff/src/templates.rs:387 — a second copy of the string.
  • The UNMASKED_WRAPPER constant itself, once nothing cites it.

The wider point, worth a moment

This is a third kind of drift, and the issue templates only name two.
finding_no_longer_reproduces.yml distinguishes ANALYZER DRIFT (the program
gets a different answer) from GENERATOR DRIFT (the recipe builds something
else). This is neither: the model of the analyzer went stale, and nothing
watches for that.

It is not confined to this rule. All 66 violations point the same way —
49 of them read "predicted RC001 at warning tier only, but it was promoted to
Confirmed — the documented rule says this construct is never witness-promoted"

— and zero point the other way. Across the same run reconverge disagreed
with an oracle 0 times (107 AgreementBug, 34 AgreementSafe, 6
AnalyzerUnsupported). So the violations are measuring how far the model has
fallen behind, not how wrong the analyzer is.

Fixing this rule fixes 14 of the 66. The remaining 52 are the same shape
against other quoted limitations, and deserve their own pass — possibly a
mechanism that checks each quoted basis still exists upstream, which would have
caught this one automatically.

Done when

The wrapper cases predict a finding rather than silence, conformance --mutants no longer reports them as violations, and the deleted test is quoted
nowhere.

Measured against crates.io 0.4.0 on 2026-08-28.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions