skip to content
agentmash get started
docswhat counts as a conflict

what your agent sees

what counts as a conflict

Two questions, asked of every edit.

Same file? The original test, and still the first one. Someone else's agent wrote this exact path inside the window (default 30 minutes) — you should know before you touch it.

Same symbol? The one that costs a team an afternoon. Alice changes the signature of an exported function in src/models/user.ts. Bob's agent is three files away in src/api/handlers.ts, building against the old signature. No path matching can see that, because there is no shared path. AgentMash sees it because the hooks exchange symbols:

  • PostToolUse works out which exported declarations an edit changed. An edit inside a function body never repeats the export function line, so the hook reads the file it just wrote and walks back from the edit to the declaration that encloses it.
  • PreToolUse works out what the file you are about to edit is bound to — everything it imports, plus everything it exports — and sends that with the check.
  • The server matches one against the other, so a change to createUser reaches every file that imports createUser, whatever directory it lives in.

Extraction runs entirely on your machine, in the hooks, with no dependencies and no parser: comments, string bodies and template-literal bodies are blanked out, and then a careful pass over lines that begin with export reads what is left. The server never sees your code — only a list of names.

The harness behind every number below is committed, and it prints its per-file rows, every name it missed and every name it claimed wrongly, so you can check the totals against the data rather than trusting them:

bash
npm run bench:symbols            # this repo's own 51 git-tracked source files
npm run bench:symbols -- --deps  # ...plus everything in node_modules

Measured against the compiler's parse of the same files: 594 of 594 symbols on this repo's own source (100%), and 34,000 of 34,594 across 7,506 files including node_modules (98.3%) — with no false positives in either. Cost is measured cold, in a freshly spawned process per measurement, because a hook is always a fresh process and extraction is never warm: p50 2.2 ms on this repo's files, 12-14 ms on its largest (108 KB), ~19 ms on a synthetic 400 KB file, and 0.2 ms for a 9 MB file the size ceiling declines to read. The Node process the hook runs in takes ~57 ms to start and read its config before any of that (npm run bench:budget, section B).

Ground truth is the TypeScript compiler already in this repo's devDependencies — bench/ is not part of what the hooks install, which stay dependency-free.

Every holder the server returns carries a confidence:

What it means
highBoth edits touch the same exported symbol, and it is a name specific enough to mean something. The one you want to read.
mediumPaths match and at least one side sent no symbols — all v0 ever knew.
lowPaths match, both sides sent symbols, and nothing they share is evidence: two agents at opposite ends of one file, or an overlap made only of names like config.

That last row is why AGENTMASH_SCOPE=dir stopped crying wolf: a same-directory neighbour that provably shares no symbols is no longer reported at all.

When it can't tell, it says nothing extra. A language the extractor doesn't read (.py, .go, .rs), a file too large to open on the edit path, an edit it can't locate — each of these sends no symbols, and detection falls back to exactly the path matching described above. Extraction failures cost you recall, never a false alarm.

from README.md, “What counts as a conflict”