skip to content
agentmash get started
docsknown limitations

trust

known limitations

  • Identity is optional and off by default. Until a room runs agentmash secure, the server believes whatever developer, timestamp, task_hint and symbols a client sends.
  • Owning a room is not yet something you can take back. Whoever connected a room, or claimed it with its key, keeps read access to its dashboard from their GitHub account. Rotating the key does not remove them — there is no owner list to edit yet. Deleting the room does.
  • The dashboard URL contains the key unless you open it signed in, from /rooms. /r/<room-key> is a secret link; treat it like one. The browser dashboard also passes ?room= on its own requests, because a WebSocket cannot carry a header — so the key reaches proxy logs on that path. The page is sent with Referrer-Policy: no-referrer, which stops the key leaving on a Referer header, but nothing stops someone pasting the URL.
  • A developer token is a bearer string. It says whose it is; it is not bound to a machine. Anything running as your user can read it out of ~/.agentmash/credentials.json and write as you.
  • Anyone with the current key is an admin. There are no roles: whoever holds the key the repo currently carries can rotate, purge and delete. Rotating after someone leaves is the whole access-control story — and because rotation is decided by who runs it first, rotate as soon as you suspect a leak, not on a schedule you were going to get to.
  • Task hints are your prompts. The first ~500 characters of each prompt are visible to everyone in the room, and are quoted into their agents' context windows — where an agent may well echo one into a reply or a commit message. Don't paste secrets into prompts. AGENTMASH_HINTS=0 withholds yours: your presence and your files are still reported, the prompt text is not.
  • Files you changed by hand are reported by name. Edits that no tool names are read from the working tree: the files a Bash or PowerShell command changed, and at a session's first prompt the tracked files that were already uncommitted, then whatever changed between prompts. Names only, never contents. Each goes out as of when it is found, so a teammate about to edit it is warned for the usual window, and says how long ago you last wrote it. AGENTMASH_WORKTREE=0 keeps the ones your agent did not change itself on your machine. A file changed by hand while a command runs is reported as that command's, even with AGENTMASH_WORKTREE=0; deletions and reverts are not reported at all. Two sessions in one checkout report each change once: a session's own edits under its own prompt, and a change neither of them made by whichever looks first.
  • A failed report is only written down on your machine. The reporting hooks run in the background, so Claude Code shows nothing when the room turns a report away or cannot be reached. Each one leaves a line in ~/.agentmash/log/reports.jsonl (what, where, why; never a key, a token or a prompt), and npx agentmash doctor and status say so.
  • Symbol extraction is regexes, not a parser. That is the price of hooks that install by git pull. It reads only the JavaScript/TypeScript family (.ts .tsx .mts .cts .js .jsx .mjs .cjs) and only lines that begin with export, which means:
    • Bundled files miss more. export{a as b} mid-line is invisible: across the 1,763 generated files under dist/ in node_modules, recall is 97.9% against 100% on this repo's hand-written source (npm run bench:symbols -- --deps --filter=dist/). Those files are generated, so this costs little in practice.
    • Members are reached through the name you import. An edit to Store.findHolders is reported as Store, because Store is what a dependent file imports. There is no method-level granularity.
    • export * from and export = are not followed. A re-export barrel breaks the chain between the file that defines a symbol and the file that imports it.
    • Names shorter than three characters are dropped (id, or, db, and a migration's up/down) — they match everything and would drown the signal. This is a floor, not a bug: a two-character export is invisible to symbol matching and falls back to paths.
    • Attribution says nothing rather than guessing. Which exported symbol an edit landed inside is decided by placing every occurrence of the edited text: unless they all fall in the same declaration, the edit names nobody. Over 620 simulated edits across this repo's own source, that is 523 correct, 97 silent, and none wrong (npm run bench:symbols). Taking the first match instead is what produces a confident wrong answer — a body line duplicated in two functions credited to the one above — and hooks/test/hooks.test.mjs pins that case.
    • A name every project has does not earn high on its own. The reference side of a check is a whole file's imports plus its exports, so config, handler, router, store and two dozen peers are always in play. An overlap made of nothing but those is not evidence: it is reported at low for the same file, and a cross-file match resting on nothing else is not reported at all. One of them beside a real name still counts.
  • Only names are matched, not signatures. Two agents touching createUser collide even if one only renamed a local variable inside it. The window keeps that bounded, and it is the right direction to err in.
  • Non-JavaScript repos get v0. Python, Go and Rust sources send no symbols, so detection is path matching exactly as before — no worse, no better.
  • Cross-file advisories share the per-file cooldown. After an advisory for a file, the next ten minutes are quiet for that file, so a symbol collision that arrives during the cooldown waits. The cooldown is checked before the request, which is what keeps the edit path free of a round trip.
  • Paths are repo-relative. Path matching still requires teammates to work in the same repo; path case differences across operating systems aren't folded. Symbol matching is path-independent and unaffected.
  • Advisory ≠ lock. The default informs the agent; it doesn't prevent overlapping edits. AGENTMASH_STRICT=1 blocks, and its acknowledge path needs a POSIX shell — a Windows agent without one has to fall back to AGENTMASH_STRICT=0.
  • Acknowledgements are per session. The log lives in the machine's temp directory, so a new session starts clean. That is deliberate — an acknowledgement that outlived the task it was made for would be exactly the standing permission it is designed not to be.
  • The digest counts tool calls, not work. An event is one Write/Edit/ MultiEdit, so an agent that rewrites a file in twenty small edits outranks one that rewrote it once, and nothing here knows whether any of it was kept, reverted or ever committed. Read the numbers as attention, not as output. Hot zones are the sturdier signal, because who-and-when survives that distortion where counts don't. Periods are UTC-anchored, and a period is only comparable with the one before it while events survive the 7-day prune.
  • Silence is ambiguous, and stays ambiguous. The board can now say no signal instead of pretending someone is working, but it still can't tell a developer who is reading a diff from one whose laptop is shut — no client-side code runs between hooks, so there is nothing to tell it apart with. AGENTMASH_IDLE_MIN decides how long we wait before admitting we don't know.
  • A slow clock still misdates the work. Presence is judged on the server's clock, but the "edited 4 min ago" label is the client's claim, and a backdated timestamp is indistinguishable from a deliberately old one. It errs towards showing an edit as older than it was, never newer.
  • Events are pruned after 7 days by default — a room can set its own retention — and a shared server rate-limits room creation. The timeline and hot zones therefore stop at 7 days, and neither can say anything about why a place is contested — they report that people keep meeting in a directory, not which change caused it, and they see no code, only paths.
  • The MCP tools see one window at a time. They read a single /activity call, which the server truncates on a busy room; the tools say so when it happens, but they can't page.
  • The MCP server committed in a repo is frozen there. Like the hooks, it is the version init last wrote until someone runs init again and commits it; a developer whose npx agentmash login is newer runs that copy instead. A repo whose launcher predates the server being committed beside it gets the degraded launcher — the query tools report themselves unavailable, loudly — until init is run there again. The hooks keep working regardless.
  • Each teammate approves the MCP server once. AgentMash will not pre-approve it for them, so the first session after a git pull carries one dialog. Decline it and the tools are absent for that person — agentmash doctor says so.
  • Commits are retrospective. The git client reports where someone landed, not what they are doing: no work in progress, no warning before a human edits, nothing at all from someone who commits once a day. Full comparison in docs/ADAPTERS.md.
  • Not every agent tool hears the advisory before an edit. Cline hears it just after the edit, Antigravity at the start of each turn, and Continue and Zed only when they ask the MCP tools; whether Devin's and Junie's agents read it is still to be verified; and aider has no hook system at all, so it is seen through the git client. Cursor and the tools like it hear it as a refused first edit, which the agent's retry gets past. Evidence and sources per tool in docs/ADAPTERS.md.
  • The dashboard does not yet show symbols or confidence. It ranks and renders paths; the symbol overlap that produced a high holder is visible to the agent, not to the board.

from README.md, “Known limitations”