Code graph

Four queries over the workshop's own index — precise for Go, heuristic elsewhere, with a confidence on every edge.

What it is#

Four questions the index can answer, each with an agent tool and a human command.

Question MCP tool Human command Answers with
Show me this function's body code_snippet orch symbols snippet <name> {symbol, start_line, end_line, body, file_bytes}
Who calls it, and what does it call? trace_path orch symbols trace <name> {root, nodes, edges}, a confidence per edge
What does this change break? impact orch symbols impact [path...] {paths, touched, callers, edges}
What does this repo look like? architecture orch symbols arch {dirs, edges} by directory

trace_path takes an optional direction (callers, callees or both) and a depth from 1 to 5, defaulting to 2. impact with no arguments reads the working-tree diff; give it paths[] or a git_range to ask about something else. code_snippet returns at most max_lines lines, 120 by default.

Why it exists#

Reading a whole file to find one function is the most expensive habit an agent has. A snippet by line range costs a fraction of it, and a call graph answers "who else uses this?" in one round-trip instead of a dozen greps. orch already parses every file it indexes, so the graph is a by-product rather than a second tool to install and keep in sync.

Precise for Go, heuristic elsewhere#

Every edge carries a confidence, and the number is the honest part:

Confidence How the edge was resolved
1.0 The Go resolver matched an import, or the file itself
0.7 The Go resolver matched a receiver type
0.4 The generic tokenizer matched a bare Name( against the symbol table of the same language

So Go is precise and the other twenty-eight langspec languages are heuristic — a 0.4 edge is a plausible call, not a proven one. A name that resolves to no indexed symbol is dropped rather than stored, so a traversal never walks into a dangling edge.

  Go source ---> go/ast resolver ---> edges at 1.0 / 0.7
  other langs -> langspec regex   ---> symbols, then tokenizer edges at 0.4
                     |
                     v
              symbol_refs table  --> trace_path / impact / architecture

What it does not see#

The index sees symbols with a signature — functions, types, methods, classes. It is blind to constants, table names, schema flags and any name that lives inside a string. For those, grep is still the right tool. An empty result is a real answer, not a failure: it means no match, so you may create the thing locally — but do not invent a duplicate of a name you already know is shared.

How it relates to the rest#

  • The index is the same one the shared code law populates: shared scope for tagged symbols, local for everything else. Search answers shared only; the graph reads both.
  • code_snippet and trace_path record the bytes they returned against the size of the file they stood in for. Those totals surface as a graph block in orch usage, content-free.

Nothing to run here#

The graph is queried, not built: registering and indexing a folder fills it. orch index shared re-scans the registered shared paths, and orch inventory checks those folders against what the index actually holds.