Skip to content

unrooted_local_shape.py's line-oriented detector misses any root_* binding rustfmt wraps, so a rooting bug in deeply-nested code is invisible to the gate #10715

Description

@proggeramlug

Found while fixing the unrooted-local regression on PR #10668.

scripts/unrooted_local_shape.py's detector is line-oriented, so rustfmt can silently hide a finding from
it.
While fixing a genuine rooting violation, the natural fix nested the corrected code five levels deep inside
its caller. At that indentation rustfmt wrapped the binding

let mut arr = scope.root_nanbox(...);

across two lines — and the scanner stopped seeing it. The fix had to be extracted into a top-level function
(build_set_cookie_array) to keep the binding on one line and remain visible to the gate.

That is a false negative driven purely by formatting. Nothing about the code's safety changed; only its line
breaks did. Two consequences:

  1. A real rooting bug in deeply-nested code is invisible to this gate. Any root_* binding that rustfmt
    wraps — which is a function of indentation depth and identifier length, not of correctness — is simply not
    counted.
  2. It can be defeated unintentionally. Nobody has to be gaming anything; writing the fix in the obvious place
    was enough to hide it. That also means the gate's counts are not a reliable measure of the population, so
    "count went down" is weaker evidence than it looks.

This sits alongside the other finding from the same PR: --no-raise-vs $BASE_SHA returned green on a tree where
the absolute --check failed
(the variant meant to catch a regression-versus-base gave a false pass). So the
gate currently has two independent ways of not firing.

Suggested direction

Parse Rust rather than lines — syn, or at minimum join logical statements before matching. Failing that, run the
detector on rustfmt-normalised output so line breaks are deterministic, and add a self-test fixture with a
deliberately deep-nested root_* binding that the current implementation would miss.

Related: this is the same family as CLAUDE.md's "★ Four ways a gate can be unable to fail", and as #10583 /
addr_class_ratchet_baseline.txt's per-path monotonicity, where a file split could be made to pass by choosing a
region carrying no recorded debt. In all three cases the gate measures an artefact of how code is arranged rather
than the property it claims to measure.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    package-auditFound by the 2026 package audit: compiling real npm packages from source instead of native bindings

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions