Skip to content

Report truncation when a result cap is hit #32

Description

@vlsi

callers, reverse-deps, and digest --json cut their output at a default cap without saying so, so a truncated result is indistinguishable from a complete one. For an agent consuming sb, that becomes a confidently wrong answer: it reports "3 callers", sizes a refactor from that number, and moves on.

impact already handles the analogous ambiguity case well, and its note is a good template for the rest: # note: 'decodeBinary' matched 70 symbols; showing all. Use a more specific suffix (e.g. 'Type.method') to narrow.

Version: ast-bro 3.0.0 (Homebrew aeroxy/tap, bottle 64), macOS 15.5 arm64. Repro below is from pgjdbc, but nothing about it is repo-specific.

Repro

callers reports the post-cap count as if it were the total

$ sb callers decodeBinary | head -1
# 113 caller(s) for 'decodeBinary':
$ sb callers decodeBinary --limit 3 | head -1
# 3 caller(s) for 'decodeBinary':

The second header is exactly what a symbol with three callers prints. Since --limit defaults to 200, the same thing happens with no flags at all on any symbol above that count.

reverse-deps cuts the list with no note

$ sb reverse-deps pgjdbc/src/main/java/org/postgresql/api/codec/CodecContext.java | wc -l
201

That is the default --limit 200 plus one header line. Nothing in the output says the list was cut.

digest is honest in text but not in JSON

Text mode prints ... +13 more, and the per-file header carries the true member count, so a human sees the truncation. ast-bro.map.v1 carries neither a truncation flag nor a total:

$ sb digest <dir> --max-members 2 --json | python3 -c "import json,sys; print(sorted(json.load(sys.stdin)['files'][0].keys()))"
['declarations', 'error_count', 'language', 'line_count', 'path']

Proposal

  1. Text. When a cap is hit, report the total and name the flag that lifts it — # 113 caller(s) for 'decodeBinary' (showing 3; raise --limit to see the rest): — following the note impact already prints. Same shape for reverse-deps and for each impact section.
  2. JSON. Add total and truncated beside every capped collection: callers.matches[], reverse-deps, impact.sections[].entries[], and the declarations[] that digest --max-members cuts. ast-bro.context.v1 already exposes truncated, so reusing that field name everywhere would let a consumer check one thing.
  3. Depth-bounded walks. deps, reverse-deps, callers, callees, impact, and trace stop at --depth rather than truncating a list, but from the caller's side the effect is the same. A flag saying the frontier was still non-empty at the cutoff would separate "the graph ends here" from "the walk stopped here".

Minor, related

--limit exists on callers, impact, and reverse-deps but not on callees, which returned 68 rows unbounded in my repo. Whichever way that inconsistency is meant to resolve, the per-command defaults are currently discoverable only through --help: --max-members 50 (digest), --limit 200 (callers, impact, reverse-deps), --budget 8000 (context), -k 10 (search), and the --depth defaults of 1, 2, 3, and 12. sb prompt mentions none of them, so an agent working from the generated prompt cannot know a cap exists, let alone that it was hit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions