Skip to content

trail: keep the code map in .trail/cache/ - #621

Merged
anirudhkumar-nanonets merged 1 commit into
feat/trail-init-layoutfrom
feat/trail-map-in-trail-dir
Oct 15, 2026
Merged

anirudhkumar-nanonets merged 1 commit into
feat/trail-init-layoutfrom
feat/trail-map-in-trail-dir

Conversation

@anirudhkumar-nanonets

Copy link
Copy Markdown
Collaborator

Moves: none of the project's metrics directly. It finishes the clean git status from #619. After trail init, the repo's .gitignore and a root .ignore no longer change, so the only things to commit are .trail/ and .claude/settings.json. learnings_committed is the closest metric (PostHog query in daily/project.md). I didn't check its value, because this session has no Metabase access.

Stacked on #619. This PR's base is feat/trail-init-layout. Merge #619 first, then I'll rebase this onto main.

What changes

Where the map lives (src/context/map-dir.ts)

  • In a repo on trail, the code map lives in .trail/cache/. A repo counts as on trail when it has .trail/learnings/ or trail's hooks.
  • Everywhere else it stays in graft/.
  • contextDirFor and resolveContextDir both go through this one rule, so the CLI, the hooks, the status line and upkeep agree. --dir and GRAFT_DIR still win.

Kept out of git by .trail/.gitignore

  • For the trail map, the build adds cache/ to .trail/.gitignore.
  • It doesn't write the repo's .gitignore or a root .ignore. graft's map is ignored exactly as before.

An existing map moves instead of being rebuilt

  • In a repo on trail, a graft/ that holds a map is renamed to .trail/cache/ the first time anything asks where the map is.
  • Its cache folder moves with it, so the wiring stamp, session state and branch caches carry over, and nothing is redone or rebuilt.
  • A graft/ that git tracks is left alone: it dates from when the map was committed, and moving it would delete committed files.
  • Old /graft/ lines in .gitignore and old .ignore blocks are left as they are. They're harmless, and removing them would touch files this change promises to leave alone.

Finding it

  • .trail/ is hidden, so a ripgrep from the repo root skips the cards. Given .trail/cache as the path, it searches them. I checked both.
  • The session-start hook now names the real folder (repo map (.trail/cache/INDEX.md)).
  • trail's skill and agent instructions say .trail/cache/ where they said graft/.
  • trail ask, grep and callers read the map wherever it is.

Smaller

  • An edit inside .trail/cache/ counts as the map's own, not the code's.
  • Uninstall removes .trail/cache/ too.
  • Three CLI lines no longer name graft/: the subdirectory notice, trail build's help, and "no code map found". Neither does ask's "if the code map is empty".

Tests

  • New trail-map-dir:
    • each repo kind gets the right folder
    • a graft/ map moves with its cache, and git doesn't see it
    • a tracked graft/ stays where it is
    • building the trail map writes only .trail/.gitignore
    • a repo with .trail/learnings/ counts as on trail before its hook exists
    • edits inside the map are recognised as the map's own
  • Updated: trail's spelling tests and the skill test now expect .trail/cache/, and the subdirectory notice test expects the new wording.
  • By hand, in scratch repos:
    • After trail init with a real build, git status showed only .claude/settings.json, .trail/.gitignore, .trail/README.md and .trail/hook.cjs. There was no graft/ and no .ignore, and trail grep NormalizeBox answered from .trail/cache/.
    • A repo set up by graft init, with its map in graft/, then trail init: the map moved to .trail/cache/ without a rebuild.
  • Full suite on my Mac: 1,436 pass, 3 fail, 1 skipped. The 3 are the graft-to-trail tests that fail on main here because of a global demo install. Rerun with a node binary that can't see that install, all 20 tests in those files pass.

🤖 Generated with Claude Code

@trailhq-graft

trailhq-graft Bot commented Oct 15, 2026

Copy link
Copy Markdown

🌱 graft blast radius

5 areas changed → 13 areas can be affected. 64 dependent symbols, depth 2.
Tests: no test reaches Query Execution, Trail Directory Management; Context Resolution has tests the diff did not touch; 2 areas updated their tests.
Tag: @shhdwi — 11 of 18 areas

flowchart TB
  A0(("Graph Management<br/>22 symbols"))
  A1(("Host Configuration<br/>11 symbols"))
  A2(("Upkeep Operations<br/>8 symbols"))
  A3(("Build Progress Tracking<br/>6 symbols"))
  A4(("Tool Invocation<br/>4 symbols"))
  AX(("8 smaller areas<br/>13 symbols"))
  classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
  class A0,A1,A2,A3,A4 reached;
  classDef tail fill:#EEF2F3,stroke:#9AA4A9,stroke-width:1px,color:#3A4247;
  class AX tail;
Loading
Can be affected Symbols Nearest hop Reached from
Graph Management 22 src/graph/build.ts:L204-L472 buildGraph — calls, depth 1 Query Execution, Context Mapping +1
Host Configuration 11 src/hosts/instructions.ts:L12-L14 inName — calls, depth 1 Claude Integration
Upkeep Operations 8 src/upkeep-run.ts:L1-L123 upkeep-run.ts — imports, depth 1 Query Execution, Claude Integration +2
Build Progress Tracking 6 src/claude/stats.ts:L7-L11 readWiring — calls, depth 1 Context Mapping, Context Resolution
Tool Invocation 4 src/mcp/tools.ts:L248-L330 callSingleTool — calls, depth 1 Claude Integration, Context Mapping
Review Process 4 src/app/review.ts:L45-L99 reviewPullRequest — calls, depth 1 Context Mapping
7 smaller areas 9 Context Validation, build-viewer.mjs, Branch Caching, … see below
Who knows this code — 1 person across 18 areas
Area Who knows it
Claude Integration · changed @shhdwi — 1 commit, last yesterday
Query Execution · changed @shhdwi — 2 commits, last yesterday
Graph Management · affected @shhdwi — 2 commits, last yesterday
Host Configuration · affected @shhdwi — 1 commit, last yesterday
Upkeep Operations · affected @shhdwi — 1 commit, last yesterday
Tool Invocation · affected @shhdwi — 1 commit, last yesterday
Review Process · affected @shhdwi — 1 commit, last yesterday
Context Validation · affected @shhdwi — 1 commit, last yesterday
…10 further areas

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 64 dependent symbols, grouped by area

Graph Management — 22 symbols in 8 files

  • src/graph/build.ts:L204-L472 — buildGraph (calls, depth 1)
  • src/graph/check.ts:L59-L159 — checkGraph (calls, depth 1)
  • src/graph/refresh.ts:L151-L228 — ensureFreshGraph (calls, depth 1)
  • src/graph/root.ts:L23-L25 — hasGraftIndex (calls, depth 1)
  • src/graph/seed.ts:L211-L228 — seedGraph (calls, depth 1)
  • src/graph/traverse-cli.ts:L167-L243 — runCallersCommand (calls, depth 1)
  • src/graph/workspace-cli.ts:L52-L100 — runWorkspaceBuild (calls, depth 1)
  • src/graph/workspace.ts:L125-L127 — clearParentGraft (calls, depth 1)
  • src/graph/workspace.ts:L106-L108 — hasMegaGraph (calls, depth 1)
  • src/graph/workspace.ts:L146-L157 — loadWorkspaceGraphs (calls, depth 1)
  • src/graph/workspace.ts:L67-L69 — workspacePath (calls, depth 1)
  • src/graph/workspace.ts:L85-L92 — writeWorkspace (calls, depth 1)
  • src/graph/refresh.ts:L236-L262 — ensureFreshChildren (calls, depth 2)
  • src/graph/refresh.ts:L125-L142 — seedUnderLock (calls, depth 2)
  • src/graph/root.ts:L35-L45 — nearestGraftRoot (calls, depth 2)
  • src/graph/workspace.ts:L241-L559 — federateAsk (calls, depth 2)
  • src/graph/workspace.ts:L631-L656 — federateCheck (calls, depth 2)
  • src/graph/workspace.ts:L710-L723 — splitWorkspace (calls, depth 2)
  • src/graph/workspace.ts:L660-L696 — federateCallers (calls, depth 2)
  • src/graph/workspace.ts:L564-L604 — federateGrep (calls, depth 2)
  • src/graph/workspace.ts:L608-L627 — federateMap (calls, depth 2)
  • src/graph/workspace.ts:L73-L82 — readWorkspace (calls, depth 2)

Host Configuration — 11 symbols in 7 files

  • src/hosts/instructions.ts:L12-L14 — inName (calls, depth 1)
  • src/hosts/plan.ts:L1-L101 — plan.ts (imports, depth 1)
  • src/hosts/antigravity.ts:L1-L62 — antigravity.ts (imports, depth 2)
  • src/hosts/claude-global.ts:L1-L218 — claude-global.ts (imports, depth 2)
  • src/hosts/codex-hooks.ts:L1-L90 — codex-hooks.ts (imports, depth 2)
  • src/hosts/cursor-hooks.ts:L1-L115 — cursor-hooks.ts (imports, depth 2)
  • src/hosts/instructions.ts:L62-L69 — cursorRule (calls, depth 2)
  • src/hosts/instructions.ts:L16-L18 — instructionBody (calls, depth 2)
  • src/hosts/instructions.ts:L71-L77 — kiroSteering (calls, depth 2)
  • src/hosts/instructions.ts:L79-L82 — windsurfRule (calls, depth 2)
  • src/hosts/mcp-config.ts:L1-L285 — mcp-config.ts (imports, depth 2)

Upkeep Operations — 8 symbols in 4 files

  • src/upkeep-run.ts:L1-L123 — upkeep-run.ts (imports, depth 1)
  • src/cli-picker.ts:L1-L517 — cli-picker.ts (imports, depth 2)
  • src/engine.ts:L109-L119 — ask (calls, depth 2)
  • src/engine.ts:L64-L74 — init (calls, depth 2)
  • src/engine.ts:L77-L79 — check (calls, depth 2)
  • src/engine.ts:L92-L102 — graph (calls, depth 2)
  • src/engine.ts:L83-L85 — checkGraph (calls, depth 2)
  • src/upkeep.ts:L200-L202 — stampPath (calls, depth 2)

Build Progress Tracking — 6 symbols in 5 files

  • src/claude/stats.ts:L7-L11 — readWiring (calls, depth 1)
  • src/claude/sync-run.ts:L8-L17 — realBuild (calls, depth 1)
  • src/claude/build-progress.ts:L45-L83 — buildGraphWithProgress (calls, depth 2)
  • src/claude/state.ts:L94-L94 — sessionDir (calls, depth 2)
  • src/claude/statusline.ts:L18-L24 — resolveStats (calls, depth 2)
  • src/claude/sync-run.ts:L19-L33 — runSync (calls, depth 2)

Tool Invocation — 4 symbols in 2 files

  • src/mcp/tools.ts:L248-L330 — callSingleTool (calls, depth 1)
  • src/mcp/server.ts:L1-L156 — server.ts (imports, depth 2)
  • src/mcp/server.ts:L61-L66 — advertised (calls, depth 2)
  • src/mcp/tools.ts:L217-L245 — callTool (calls, depth 2)

Review Process — 4 symbols in 4 files

  • src/app/review.ts:L45-L99 — reviewPullRequest (calls, depth 1)
  • src/app/review-process.ts:L180-L184 — childReviewer (references, depth 2)
  • src/app/review-worker.ts:L67-L87 — run (calls, depth 2)
  • src/app/server.ts:L31-L37 — AppSeams (references, depth 2)

Context Validation — 3 symbols in 2 files

  • src/context/build.ts:L146-L374 — buildContext (calls, depth 1)
  • src/context/check.ts:L39-L112 — checkContext (calls, depth 1)
  • src/context/check.ts:L131-L141 — indexFreshness (calls, depth 1)

build-viewer.mjs — 1 symbol in 1 file

  • scripts/build-viewer.mjs:L1-L45 — build-viewer.mjs (calls, depth 2)

Branch Caching — 1 symbol in 1 file

  • src/notes/branches.ts:L75-L77 — cachePath (calls, depth 2)

…4 further symbols not listed.

Test signal per changed area — 2 ✓ · 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.

  • ✓ Context Mapping — 4 of 6 reached · 1 test file changed here: test/trail-map-dir.test.ts
    • not reached: isTrailMapDir, moveOldMap
  • ⚠ Context Resolution — 1 of 1 reached · 2 test files reach it, none changed here
  • ✓ Claude Integration — 3 of 4 reached · 3 test files changed here: test/hosts-trail.test.ts, test/trail-map-dir.test.ts, test/trail-notes.test.ts
    • not reached: main
  • ✗ Query Execution — 0 of 4 reached · no test file reaches it
    • not reached: queryRoot, runCheckCommand, lexical, targets
  • ✗ Trail Directory Management — 0 of 1 reached · no test file reaches it
    • not reached: ignoreInTrailDir
49 test suites also reference this code

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

  • test/ask-index.test.ts
  • test/ask.test.ts
  • test/claude-format.test.ts
  • test/claude-hooks.test.ts
  • test/claude-init.test.ts
  • test/claude-shim-template.test.ts
  • test/claude-state.test.ts
  • test/claude-stats.test.ts
  • test/cli-picker.test.ts
  • test/container-extract.test.ts
  • test/context-checkpoint.test.ts
  • test/context-only-dir.test.ts
  • test/context.test.ts
  • test/covers.test.ts
  • test/generic-extract.test.ts
  • test/graft-to-trail.test.ts
  • test/graph-go.test.ts
  • test/graph-incremental.test.ts
  • test/graph-invariants.test.ts
  • test/graph-java.test.ts
  • …29 more

graft blast · refs/graft/base...HEAD · depth 2 · 15 changed files

Open the interactive graph → — click an area to see the code that changed, and the line that reaches it.

@anirudhkumar-nanonets
anirudhkumar-nanonets merged commit ff124cf into feat/trail-init-layout Oct 15, 2026
@anirudhkumar-nanonets

Copy link
Copy Markdown
Collaborator Author

Folded into #619, which now carries this commit.

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