Skip to content

--uses answers a silent count="0" for a :: selector that --callers resolves #164

Description

@joyful-ii-V-I

What is wrong

Every symbol-taking verb accepts the two :: spellings ripwire prints about itself: the canonical id
path::scope::name that every map row carries in id=, and the Scope::name that --edit-check
prints as sym=. --callers, --callees, --impact and --expand all resolve them. --uses
resolves them too — and then answers count="0", with no rows and no disclosure, for symbols that
plainly have call sites. A zero that reads as "defined, and nothing uses it" is exactly the
misreading CLAUDE.md non-negotiable 3 exists to prevent, and the callers answer's own next=
pointer sends the reader straight into it.

The evidence

On the test/declinefix fixture, three spellings of one symbol:

--callers=cpp/pair/one.cpp::One::ctwin   count="1"  next="--uses=cpp/pair/one.cpp::One::ctwin"
--uses=cpp/pair/one.cpp::One::ctwin      defs="1" external="0" count="0"      (no rows)
--uses=cpp/pair/one.cpp:ctwin            count="1"  <u role="call" p="cpp/pair/user.cpp:3" …/>

On this repository itself, --callers=NoteIndex::empty counts 816 callers and
--uses=NoteIndex::empty counts 0.

The cause is one comparison: resolveUsesSelector in src/verbs_navigate.h keeps the whole ::
spelling as the site match key, and collectUseSites compares that key against reference names,
which are always bare. The same zero reaches --safe-delete's uses=, --verify="uses(…)" and
unused(…), which share the scan, and the MCP uses verb, which carries its own copy of the
comparison. It was characterized across 16 selectors in C++, Python and Rust.

test/usesselectorcheck.sh already pins the gap. On a build of main it is ALL PASS, 57 checks
with 12 of them labelled KNOWN GAP; each asserts today's wrong answer and names its FIXED
expectation in a comment beside it. Against a wrapper faking the naive "strip the scope" fix, 12
arms go red — nine read MOVED, and the two precision controls and the wrong-scope control fail.

Size

Good first issue, though not a trivial one. The root cause is a single comparison in a single
function, and fixing it there reaches all three CLI verbs at once; there is no new gate file to
write, because the arms to flip already exist and every code pointer is verified. What keeps it from
being tiny: the MCP twin holds its own copy of the comparison and needs a decision, the --uses
legend has 25 bytes of budget left, and --help plus the generated docs/COMMANDS.md move with the
change.

Where to start

prompts/help-wanted/uses-qualified-selector.md is a self-contained prompt for a coding agent. It
carries the reproduction, the characterization table, file:line pointers with their symbols, the fix
shape and its edges, the honesty rules that apply, the acceptance criteria and the traps. Like every
prompt in prompts/, it ends by writing a plan and stopping — a maintainer agrees the plan
before any code is written.

Acceptance is flipping every KNOWN GAP arm in test/usesselectorcheck.sh to its FIXED line, red
against a build of main and green on the fix, with every control unchanged.

A sibling kit, prompts/help-wanted/next-uses-bare-name.md, changes the callers answer's next= on
a declined call and names this bound :: case as a separate, older gap. The two touch different
code, read the same fixture, and can land in either order; neither should absorb the other.

Comment here to claim it.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions