Skip to content

Build a missing code map on the first trail query - #704

Merged
anirudhkumar-nanonets merged 2 commits into
mainfrom
feat/build-map-on-first-use
Oct 27, 2026
Merged

anirudhkumar-nanonets merged 2 commits into
mainfrom
feat/build-map-on-first-use

Conversation

@anirudhkumar-nanonets

Copy link
Copy Markdown
Collaborator

A repo on trail that this machine never built answered every trail query with learnings and no code, so Claude went back to grep for the rest of the session. Now the first query there starts a full build in the background and waits up to 90s for it.

  • Only repos on trail (map dir .trail/cache). Graft repos, a --dir map and the home folder still build nothing.
  • One detached build: claude/sync-run.js with a 10-minute limit instead of the end-of-turn 2 minutes. Queries that arrive meanwhile wait on the same lock.
  • Hook children run with GRAFT_FIRST_BUILD_WAIT_MS=0, so the prompt hook starts the build and answers within its budget.
  • Past 90s the note says the map is still building and to rerun the same command, instead of "no matching nodes, try different words".

Tried on NanoNets/assign (8.5k files, no map): the query that came back empty built the map in 72s and returned the task feed code.

Moves: share of trail query events with hit=no. 7.8% on 2026-10-27 (12,798 of 164,008 queries that report a hit, last 7 days), PostHog Postgres (Metabase db 11): SELECT properties->>'hit', count(*) FROM posthog_event_full_view WHERE event = 'query' AND properties->>'cli_name' = 'trail' AND timestamp >= now() - interval '7 days' GROUP BY 1

Tests: 5 new. trail check: no conflicts. The full suite has 3 failures that also fail on main on a machine with trail installed globally: two expect no trail on PATH, one expects "graft is now Trail-code".

🤖 Generated with Claude Code

@trailhq-graft

trailhq-graft Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🌱 graft blast radius

3 areas changed → 3 areas can be affected. 8 dependent symbols, depth 2.
Tests: no test reaches Build Execution, State Locking; 1 area updated its tests.
Tag: @shhdwi — 5 of 6 areas · s4kura — State Locking · @Rakly3 — Build Execution

flowchart TB
  A0(("Claude Hook Integration<br/>4 symbols"))
  A1(("MCP Server<br/>2 symbols"))
  A2(("CLI Entry Point<br/>2 symbols"))
  classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
  class A0,A1,A2 reached;
Loading
Can be affected Symbols Nearest hop Reached from
Claude Hook Integration 4 src/claude/hooks.ts:L63-L67 checkStaleCount — calls, depth 1 Build Execution
MCP Server 2 src/mcp/tools.ts:L219-L247 callTool — calls, depth 1 Graph Refresh
CLI Entry Point 2 src/cli.ts:L251-L261 refreshBefore — calls, depth 1 Graph Refresh
Who knows this code — 4 people across 6 areas
Area Who knows it
Graph Refresh · changed 贾旭卿 — 1 commit, last 2mo ago
Build Execution · changed @shhdwi — 5 commits, last 4d ago · @Rakly3 — 1 commit, last 5d ago
State Locking · changed @shhdwi — 1 commit, last 4d ago · s4kura — 1 commit, last 5d ago
Claude Hook Integration · affected @shhdwi — 13 commits, last 4d ago
MCP Server · affected @shhdwi — 20 commits, last yesterday
CLI Entry Point · affected @shhdwi — 47 commits, last today

Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no @ has no GitHub handle in its commit email — tag them by hand, or add a .mailmap entry. A suggestion from history, not a CODEOWNERS rule.

All 8 dependent symbols, grouped by area

Claude Hook Integration — 4 symbols in 2 files

  • src/claude/hooks.ts:L63-L67 — checkStaleCount (calls, depth 1)
    64: const r = graftJson(dir, withContextDirArg(dir, ['check', '.', '--json']));
  • src/claude/prompt-hook.ts:L218-L236 — askGraph (calls, depth 1)
    234: const ask = await graftJsonWithin(dir, askArgs, timeout, prompt);
  • src/claude/hooks.ts:L91-L104 — handlePostEdit (calls, depth 2)
  • src/claude/prompt-hook.ts:L258-L291 — handlePrompt (calls, depth 2)

MCP Server — 2 symbols in 2 files

  • src/mcp/tools.ts:L219-L247 — callTool (calls, depth 1)
    238: : await ensureFreshGraph(root, { contextDir: dirOverride });
  • src/mcp/server.ts:L98-L251 — startMcpServer (calls, depth 2)

CLI Entry Point — 2 symbols in 1 file

  • src/cli.ts:L251-L261 — refreshBefore (calls, depth 1)
    258: : await ensureFreshGraph(root, { contextDir: globalDir, disabled });
  • src/cli.ts:L1-L2705 — cli.ts (calls, depth 2)
    35: import { ensureFreshChildren, ensureFreshGraph, refreshNote } from "./graph/refresh.js";
Test signal per changed area — 1 ✓ · 2 ✗

Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.

  • ✓ Graph Refresh — 1 of 4 reached · 1 test file changed here: test/graph-refresh.test.ts
    • not reached: buildMissingMap, firstBuildWait, startFirstBuild
  • ✗ Build Execution — 0 of 5 reached · no test file reaches it
    • not reached: hookChildEnv, graftJson, graftJsonWithin, realBuild, main
  • ✗ State Locking — 0 of 1 reached · no test file reaches it
    • not reached: lockHeldIn
4 test suites also reference this code

4 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.

  • test/graph-follow-submodules.test.ts
  • test/graph-load.test.ts
  • test/graph-seed.test.ts
  • test/mcp-tools.test.ts

⚠️ 1 changed file not in the graph (.trail/learnings/2026-10-27-a-repo-on-trail-with-no-anirudhkumar.md) — no parser claims the extension, or the index predates the file.

graft blast · origin/main...HEAD · depth 2 · 7 changed files

Open the interactive graph → — click an area to see its dependent symbols at file:line.

…st-use

# Conflicts:
#	src/claude/hook-io.ts
#	src/claude/hooks.ts
github-actions Bot added a commit that referenced this pull request Oct 27, 2026
@anirudhkumar-nanonets
anirudhkumar-nanonets merged commit 4067db5 into main Oct 27, 2026
8 checks passed
github-actions Bot added a commit that referenced this pull request Oct 27, 2026
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.

1 participant