Who calls this, and what breaks if I change it

Call graph around one symbol, and the blast radius of a diff — without reading a single whole file.

Prompt#

Who calls ResolveAgentCmd, and what breaks if I change it?

What the Chair does#

Queries the workspace's own symbol index: callers first, then the reach of the files you are about to touch.

MCP calls#

trace_path({ "symbol": "ResolveAgentCmd", "direction": "callers", "depth": 2 })

Then the blast radius of the change itself:

impact({ "paths": ["client/internal/config/config.go"] })

Or against a branch range instead of the working tree:

impact({ "git_range": "main...HEAD" })

And read only the body you actually need:

code_snippet({ "symbol": "ResolveAgentCmd", "max_lines": 120 })

CLI equivalents: orch symbols trace <name>, orch symbols impact, orch symbols snippet <name>, orch symbols arch.

Expected response#

trace_path returns {root, nodes, edges}, one confidence per edge. impact returns {paths, touched, callers, edges} — touched: [] when the diff reaches nothing indexed. architecture returns {dirs, edges}, a directory-level map worth reading before you decide where a change belongs.

Gotchas#

  • Read the confidence. 1.0 means the resolver matched an import or the file itself; 0.7 matched a receiver type; 0.4 is the generic tokenizer matching a bare Name( against same-language symbols. A 0.4 edge is a lead, not a fact.
  • A miss is a suggestion, not an error. A name the index does not hold comes back as {found: false, hint, did_you_mean: [...]} — try one of those names rather than falling back to grep. Languages Orchemax has no parser for contribute no edges at all.
  • The graph only sees symbols with a signature. Constants, table names, schema flags, feature codes and anything that lives inside a string are invisible to trace_path — grep for those. This is the one case where reading files still wins.
  • impact with no arguments uses your own checkout's changes (git diff --name-only HEAD plus untracked files, run where you are — a worker's worktree, not the workspace root). With paths given, git_range is ignored; with neither and nothing changed, pass symbol: "Name" instead.
  • depth is capped at 5 and defaults to 2. Depth is where these queries get expensive; widen it once, not by habit.
  • Untagged code is still visible here. Unlike search_shared_symbols, which answers with orch:export symbols only, the graph tools read local definitions too — so a private helper that nobody exported still shows up as a caller.
  • Your own project is always readable. A worker reading a symbol of the code it was dispatched to work on gets the body from its own worktree, local (untagged) symbols included. Only project: naming another project is restricted to orch:export symbols, and the refusal says so.
  • Replies have a byte ceiling and degrade into it. trace_path 2,000 B, impact 3,000 B, architecture 4,000 B, code_snippet the body plus 200 B. Rows are ranked by reference count and capped at limit (20); a capped list carries has_more and a cursor. Ask once with verbose: true if you really want the whole shape.
  • session is optional now. The seat is read from ORCH_SESSION; pass session only when you are driving the tools on another seat's behalf.