Skip to content

blast-radius's embedded [deps] section is nondeterministic across identical runs #153

Description

@JordanCoin

Version: 4.4.2 (Homebrew) · macOS

Summary

Running blast-radius repeatedly on an unchanged repo at a fixed ref produces different function and dependency counts each time. Only the embedded [deps] sub-section varies; the rest of the output is stable.

Repro

Same repo, same ref, no edits between runs:

codemap blast-radius --text --ref <ref> .   # Go repo, 4 consecutive runs

Actual

242 functions · 8 deps
174 functions · 3 deps
191 functions · 7 deps
253 functions · 2 deps

Same on a Swift repo, and the format also shifts between output modes:

--text:      72 functions / 57 / 63
--markdown:  81 / 52 / 81

Scope — this is narrower than it looks, which may help localize it

These are fully deterministic (5/5 identical runs each):

  • codemap --deps --json .
  • codemap --importers <file> (also verified set-identical to grep -rl, 31/31)

And within blast-radius itself, the importer counters are stable run to run:

files_with_dependents=4
impacted_outside_diff=12/24

So the standalone deps scanner is fine. Only the copy of it embedded in blast-radius races.

Likely cause

Looks like a concurrent scan that's cut off by blast-radius's character budget or a timeout — whichever workers have finished when the budget is hit is what lands in the output. That would explain why counts vary downward-ish and why the standalone command, which has no such budget, is stable.

Why it matters

Anything comparing two blast-radius runs — CI gating, a diff of before/after, an LLM told "here is the dependency context" — sees changes that didn't happen. Nondeterministic output also makes the tool hard to snapshot-test.

Suggested fix

Collect results deterministically before applying the budget: gather the full set, sort by a stable key, then truncate. If the truncation is intentional, report it (showing 174 of N functions) rather than presenting a partial count as the total.

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