Skip to content

Census: a no-void probe that starts failing reads as an improvement and the lane stays green #3366

Description

@louistrue

The watertightness census treats a host's no-void probe going dark as the host getting better, and the lane stays green.

The mechanism

HostRow::is_torn_solid reads four things: open > 0, a closed-solid representation, !far, and pre != PreVoid::Failed. classify has a symmetric pair of arms on that predicate:

if r.is_torn_solid() && !g.is_torn_solid() {
    c.worse_gated.push("newly a genuine watertightness defect (...)");
} else if !r.is_torn_solid() && g.is_torn_solid() {
    c.better.push("no longer a genuine watertightness defect");
}

When process_no_voids starts returning None for a host, pre flips Open(n) -> Failed with open, tris, coll, far and alt all unmoved. The second arm fires, and nothing else in classify has anything to say, so the only reason attached to the host is that it is no longer a genuine defect.

reclassifications does not carry pre. It carries rep and far, on the grounds that those move is_torn_solid without any count moving, which is exactly what pre also does. So the host is not reclassified either.

What that costs

The host lands in improved. requires_bless() is false, no assert covers improved, and the derived closed solids that are not watertight ceiling falls, so the got <= want check passes too. The lane is green.

Measured directly against the current classifier:

golden  SweptSolid open=3 tris=100 pre=0
run     SweptSolid open=3 tris=100 pre=x

regressed=0 changed=0 improved=1 requires_bless=false
IMPROVED reasons=["no longer a genuine watertightness defect"]

This is the shape the module header already calls the worst of the three: a host that stops producing takes its own defects out of every sum, so a coverage loss reads as an improvement. Here it is the secondary diagnostic rather than the mesh, but the effect on the gate is the same. The pre reading is what separates "arrived torn" from "the boolean tore it", so losing it silently costs the census the attribution it exists to provide.

Suggested fix

Carry pre in reclassifications alongside rep and far, since the membership test for that list is "moves is_torn_solid without moving a count" and pre satisfies it. A reclassification outranks the gated flip, so the host files under changed, which requires a bless and is red.

This is not free and is why it was not folded into #3219's instrument PR:

  • It re-routes the other direction too. A probe that starts running (Failed -> Open(n)) currently files as regressed via worse_gated; under the fix it files as changed. Both are red and both require a bless, but the label changes.
  • It changes the expectations of a pre-existing test, a_no_void_pass_that_stops_failing_makes_the_host_a_gated_defect.

Both are defensible under the module's own doctrine, which says a relabel that moves a host into the gated population without counts moving is a change of question rather than a degradation. It wants its own review rather than a late addition to a PR scoped to the triangle-count classifier.

Provenance

Found in review of the census re-tessellation split. Deferred there deliberately, on the record, because it is pre-existing and orthogonal to that PR's scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions