{"slug": "we-ditched-worktrees-one-folder-one-rule", "title": "We ditched worktrees: one folder, one rule", "summary": "Ogcode built a file-write gate called hedit that lets multiple AI coding agents share a single project folder instead of using Git worktrees, which the team found created merge conflicts at the delivery stage rather than preventing them. The gate tracks a per-file revision number, a size-and-mtime fingerprint, and a per-agent bookmark of the last revision actually read, blocking any write that would overwrite a change the agent has not seen while ignoring an agent's own edits. The team says the approach removes the copying and merge steps entirely.", "body_md": "Picture a kitchen with seven cooks. Each cook has their own dish to make,\n\nand they all share the same pans, the same ingredients, the same shelves.\n\nIf a cook never looks at a pan before using it, they will eventually dump\n\ntheir sauce into a bowl someone just filled with something else. The dinner\n\nis ruined, and nobody can even say who ruined it.\n\nThat is exactly the problem you get when you let many AI coding agents\n\nwork on one project at the same time. This post is about how we solved it\n\nin Ogcode, and why the popular solution, making copies, made things worse\n\ninstead of better.\n\nRead full article here : [https://ogcode.in/blog/hedit-no-worktrees/](https://ogcode.in/blog/hedit-no-worktrees/)\n\nA coding agent is an AI program that doesn't just talk about code. It\n\nactually does things: it reads your files, edits them, runs commands in\n\nyour terminal, and reports back. One agent is one helper.\n\nOgcode lets one agent be the boss. We call it the orchestrator. When you\n\ngive the orchestrator a big job, it splits the work into pieces and\n\nspawns helpers of its own, called teammates. One teammate might write the\n\ndocs, another might fix a bug, another might clean up tests. They all run\n\nat the same time, in the same project folder.\n\nWhich brings us to the problem.\n\nTwo agents can pick up the same file without meaning to. Here's how it\n\ngoes wrong:\n\nAgent A just erased B's work without ever seeing it. A has no idea, B\n\nhas no idea, and you only find out much later, when something is broken.\n\nGit, the tool that tracks your code, has a trick for this called a\n\nworktree. A worktree makes a complete second copy of the project folder,\n\nso two streams of work never touch. Agent A works in copy one, Agent B\n\nworks in copy two, and you merge the results at the end.\n\nIt sounds safe, and for a human working on two things it can be. For a\n\nteam of agents it's a trap:\n\nYou built two kitchens, cooked two dinners, and still had the same fight.\n\nIt just happens at the delivery door instead of at the stove, where the\n\ncooks could have settled it.\n\nOgcode does the opposite of making copies. Every agent, the orchestrator\n\nand every teammate, works in the same folder, on the same files. There is\n\nno copying step and no merge step at all.\n\nInstead there is one rule, and it is enforced by a gate we built into\n\nevery tool that touches files. We call it hedit.\n\n**Nobody writes over a change they haven't seen.**\n\nThat's it. Simple to say, and it has to work perfectly or the whole idea\n\nfalls apart. Here's how the gate makes it true.\n\nFor every file in the project, the gate keeps a small notebook with\n\nthree entries.\n\n**A revision number.** Think of the ticket counter at a bakery. Every\n\ntime someone changes a file, its number goes up by one. Change a file\n\nten times and it goes from 3 to 13. The number never goes backwards, so\n\nthe question \"has this changed?\" is just \"is the number bigger than it\n\nwas?\" No clocks, no guessing.\n\n**A fingerprint.** A super quick check of the file's size and the time\n\nit was last touched. It's like glancing at a book's cover to see if it\n\nchanged, without rereading every page. The gate uses this to spot that\n\nsomething moved, and then the next read does the real checking.\n\n**A bookmark.** For every agent, the revision number that file had the\n\nlast time that agent truly read it. That qualifier matters: an agent\n\nthat only asked for a quick summary or a file listing doesn't get a\n\nbookmark, because it never saw the actual words. You can't promise you\n\nread a page you never saw.\n\nNothing in it is a lock, a copy, or a piece of merge machinery. The gate\n\nis just a very careful diary.\n\nBefore any edit or write lands, the gate asks one question: has anyone\n\nelse changed this file since you last read it?\n\nThe gate ignores changes the agent made itself. That's important,\n\nbecause agents often fix their own mistakes and try again. Nobody should\n\nbe stopped from correcting their own work.\n\nBut if a different agent changed the file, the edit is refused, and the\n\nagent gets a message like this one:\n\n```\nFile changed by another agent since you read it: server.go\n\nNothing was written. Your edits were NOT applied.\n\nYour last read was revision 7. The file is now at revision 9.\n\n[1] rev 8, 09:14:07, docs-team (edit)\n    note: fix the wrong port number\n    @@\n    - old lines ...\n    + new lines ...\n\n[2] rev 9, 09:14:52, nav-fix (edit)\n    note: rename the navigation section\n    @@\n    - old lines ...\n    + new lines ...\n\nRe-read the file and re-apply your change against the current content.\n```\n\nThat message is the whole feature. Look at what it gives the losing\n\nagent: the names of everyone who touched the file, every change it\n\nmissed, with the old and new lines right there, and a clear next step.\n\nIt doesn't invite the blind retry a bare error does. It's a full\n\ncatch-up report.\n\nThe agent then rereads the fresh file and reapplies its edit on top of\n\nwhat exists now. Nothing gets overwritten, and nothing gets lost.\n\nWe call this refuse-and-catch-up. Compare it to the copy-and-merge\n\nworld: there, the collision is discovered after both agents are\n\nfinished, by a human, in text that stopped making sense an hour ago.\n\nHere, the collision is caught in the exact moment both agents are still\n\nworking, and one of them fixes it in seconds while the other keeps\n\ngoing. Nobody rings a bell to summon you.\n\nEdits can be checked before they happen. A terminal command cannot,\n\nbecause it's a full shell: it might rewrite five files in ways the gate\n\ncan't look inside.\n\nSo the gate does the next best thing. It checks afterwards. When a shell\n\ncommand finishes, the gate looks at every file it tracks and notes any\n\nthat changed. The note says what command ran and that something moved,\n\nand that is honestly all it knows.\n\nOne detail we're proud of: the gate does not guess who changed the file.\n\nThe terminal command might have been run by any agent, or touched files\n\nsomeone else edited indirectly. Blaming the runner would be a lie, and\n\nlies in a system like this are poison. So the note says \"changed,\n\nauthor unknown,\" and every other agent gets stopped and shown the change\n\non its next edit, exactly as if a named agent had done it.\n\nThere is one tiny hole in the fingerprint, and we chose it on purpose.\n\nTwo changes could fit inside the same file tick and be invisible. To\n\nclose that hole we would have to reread every tracked file after every\n\nsingle command, which would be slow everywhere to fix a rare case. And\n\nthe moment anyone goes to edit that file, the stale copy gets caught\n\nanyway. We picked the fast gate with a hairline gap over the slow gate\n\nwith none.\n\nThe gate keeps the files safe. The team itself has a few rules on top:\n\n`docs-team` above, so you can always tell who\ndid what.\nEvery change that lands goes into a permanent diary, with the file, the\n\nrevision, who made the change, which tool they used, a one line reason,\n\nand the actual difference between old and new text. The diary never\n\nshrinks, so even long after an agent is gone you can still look up\n\nexactly what it did.\n\nThat diary is where the one-folder rule pays off a second time: it makes\n\nthe whole job auditable.\n\nThink about auditing when agents work on copies. Three branches, three\n\nstreams of commits, one merge commit at the end that mashes everything\n\ntogether. Ask later \"why does this function look like this?\" and the\n\nhonest answer is archaeology: dig through chat logs and terminal\n\nscrollback, hoping someone wrote the reason down somewhere.\n\nIn Ogcode, asking \"what happened to this file?\" gets a straight answer.\n\nHere is the shape of it, for the file from the refusal message above,\n\ncovering one job:\n\n```\nrev 8   09:14:07  docs-team     edit   fix the wrong port number\nrev 9   09:14:52  nav-fix       edit   rename the navigation section\nrev 10  09:15:31  docs-team     edit   rewrite the failing test\nrev 11  09:16:03  orchestrator  edit   update the config example\n```\n\nEvery line is one landing, and every landing carries the old and new\n\nlines beside it, so you open the record and see the actual change, not\n\njust the fact that a change happened.\n\nAnd the reason is not luck. In Ogcode, an agent cannot edit a file\n\nwithout writing one line on why. It is a required part of the edit, the\n\nsame way the file itself is. So the first thing every record answers is\n\nexactly the question you will have later: what changed, and why. Nobody\n\nhad to remember to document anything after the fact.\n\nLine the records up across a whole feature and the story falls out for\n\nfree: which files iterated and how many times, which agent owned each\n\nchange, what it actually did to the file, and where two agents met and\n\nsettled it. The settling comes from the collide-and-refuse moment\n\nearlier: the diffs a refused agent gets are the very same diary rows,\n\nso the catch-up report and the audit trail are one system. You could\n\nread a whole feature's records top to bottom like a story, which the\n\ncopies-and-merge world can't give you.\n\nWe are honest about what's missing there: the diary has an interface for\n\nprograms but not a real page in the web UI yet. That's coming.\n\nBecause git solves a problem the agents don't have. Git is built for\n\nwriters who finish their work first and meet later. Two agents are never\n\nfinished. They're in the middle of the job, still holding the thinking\n\nbehind every change, still able to redo anything.\n\nSo Ogcode coordinates where agents are strong and git is weak: at the\n\nmoment of writing, while both writers still know what they meant. Git\n\nstays underneath for saving history. It's a great history keeper. As a\n\nbouncer at the door of a busy kitchen, it's out of its depth.\n\nNo post about our own system should pretend it's perfect. Here's what\n\nwe'd still like to build:\n\nLots of agents on one project don't need to be copies of each other.\n\nThey need to live in one folder and follow one rule: nobody writes over\n\na change they haven't seen. When that rule is enforced with a refusal\n\nthat shows you everything you missed, the agents settle their own\n\nconflicts while the work is still warm, and you never have to stand\n\nbetween two sets of edits with a broom.", "url": "https://wpnews.pro/news/we-ditched-worktrees-one-folder-one-rule", "canonical_source": "https://dev.to/prasenjeetsymon/we-ditched-worktrees-one-folder-one-rule-32d8", "published_at": "2026-10-28 12:08:00+00:00", "updated_at": "2026-10-28 12:11:42.450744+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["Ogcode", "Git", "hedit"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/we-ditched-worktrees-one-folder-one-rule", "markdown": "https://wpnews.pro/news/we-ditched-worktrees-one-folder-one-rule.md", "text": "https://wpnews.pro/news/we-ditched-worktrees-one-folder-one-rule.txt", "jsonld": "https://wpnews.pro/news/we-ditched-worktrees-one-folder-one-rule.jsonld"}}