Skip to content

Add opt-in blast-radius mode to detect_changes (#89) - #92

Merged
AliRezaTaleghani merged 1 commit into
mainfrom
detect-changes-blast-radius
Aug 27, 2026
Merged

AliRezaTaleghani merged 1 commit into
mainfrom
detect-changes-blast-radius

Conversation

@AliRezaTaleghani

Copy link
Copy Markdown
Contributor

What

Adds an opt-in "blast radius" mode to detect_changes (issue #89): in
addition to the directly-changed symbols, optionally walks inbound callers
(direct and transitive) of each changed function, plus a summary of how
much the change actually touches.

Schema

detect_changes MCP tool gains three new optional parameters, named/clamped
identically to trace_call_path's own (so an agent that's used one
immediately understands the other):

  • blast_radius (boolean, default false)
  • depth (integer, default 3, clamped via the existing clamp_depth/SERVER_MAX_DEPTH)
  • limit (integer, default 100, clamped via the existing clamp_limit/SERVER_MAX_LIMIT)

When blast_radius=false (the default): response is the exact same JSON
array of directly-changed symbols the tool has always returned, taking the
exact same code path (index::detect_changes) it always has.

When blast_radius=true: response becomes

{
  "direct": [ ...same node shape as before... ],
  "transitive_total": 7,
  "transitive_shown": 7,
  "transitive": [ ...TracedNode-shaped, with provenance/resolution/confidence... ],
  "summary": { "direct_count": 2, "transitive_count": 7, "files_touched": 4 }
}

Reuse, not a new subsystem

Per the issue's explicit guidance, this deliberately builds on what already
exists rather than adding a new traversal/bounding scheme:

See ADR 0016 (docs/NexusContext-Wiki/ADRs/0016-blast-radius-mode-reuses-trace-calls-not-a-new-subsystem.md)
for the full writeup.

Default-behavior-unchanged guarantee

crates/nexus-index/src/queries.rs::detect_changes is now a thin wrapper
around a shared detect_changes_direct helper that also backs the
blast-radius path - detect_changes's own signature/behavior is otherwise
untouched. The MCP handler's blast_radius=false branch calls that same
detect_changes and returns immediately, never touching the BFS code at
all - so there's no added latency for callers who don't ask for it.

Verified by:

  • default_detect_changes_output_is_unchanged_by_blast_radius_existing -
    asserts the plain detect_changes(&dir) call and the .direct half of
    detect_changes_blast_radius(&dir, 3) agree exactly on a real indexed
    repo.
  • The pre-existing detect_changes_enforces_allowed_roots integration test
    (crates/nexus-index/tests/path_security.rs) still passes unmodified.

Tests

  • a_widely_called_function_surfaces_its_multi_hop_caller_set - a change to
    a function called by two others (one of which is itself called by a
    third) surfaces the real 2-hop caller set.
  • an_isolated_leaf_change_reports_an_empty_transitive_set_not_an_error -
    a change to a function with no callers returns an empty transitive set,
    not an error.
  • default_detect_changes_output_is_unchanged_by_blast_radius_existing -
    regression coverage for the unchanged-default guarantee above.

All three build a real git repo + graph index rather than mocking
trace_calls, so they exercise the actual git diff parsing,
nodes_overlapping mapping, and BFS together.

Verification

  • cargo build --workspace - clean
  • cargo test --workspace - all green (139 tests across nexus-index/nexusd, plus the 3 new ones)
  • cargo fmt --all -- --check - clean
  • cargo clippy --workspace --all-targets -- -D warnings - clean

Docs

  • docs/NexusContext-Wiki/MCP-Tools.md - detect_changes row updated with
    the new parameter/response shape.
  • docs/NexusContext-Wiki/ADRs/0016-blast-radius-mode-reuses-trace-calls-not-a-new-subsystem.md -
    new ADR recording the reuse decision, linked from the ADR index.

Closes #89.

https://claude.ai/code/session_01D6ND42psexN5cWTKewSpBG

Reuses GraphStore::trace_calls (the same BFS/provenance machinery
trace_call_path exposes) and the existing clamp_depth/clamp_limit
bounds, rather than a new traversal or bounding scheme.

- nexus-index: detect_changes_direct factors out the existing
  git-diff-to-NodeRecord mapping so plain detect_changes and the new
  detect_changes_blast_radius(repo_path, depth) share it exactly;
  BlastRadiusResult { direct, transitive, files_touched } carries
  per-node edge_kind provenance via TracedNode.
- nexusd: detect_changes tool gains blast_radius (bool, default
  false), depth/limit (named/clamped identically to trace_call_path).
  blast_radius=false takes the untouched pre-existing code path -
  same response shape and cost as before.
- Tests: a widely-called function surfaces its real multi-hop caller
  set; an isolated leaf function reports an empty transitive set, not
  an error; default detect_changes output is proven unchanged.
- Docs: MCP-Tools.md updated; ADR 0016 records the reuse decision.

Closes #89.

Claude-Session: https://claude.ai/code/session_01D6ND42psexN5cWTKewSpBG
@AliRezaTaleghani
AliRezaTaleghani merged commit d87e4e8 into main Aug 27, 2026
5 checks passed
@AliRezaTaleghani
AliRezaTaleghani deleted the detect-changes-blast-radius branch August 27, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Blast-radius mode for detect_changes (impact analysis)

1 participant