# Ataraxy Labs — Full Text > Concatenated markdown for every public page on ataraxy-labs.com. > Generated 2026-09-11. See llms.txt for the navigable index. --- # Home (/) --- title: "Ataraxy Labs" tagline: "The SDLC Singularity" --- # Ataraxy Labs Software, written for the things that read it. Ataraxy Labs builds the substrate for agent-native software development. Semantic version control, entity-level merges, and structured interfaces for the systems that will write most of the world's code. ## Thesis Every tool in software development was designed for human hands. ### Axiom i — Intent is scarce. Compute is not. The only irreducible bottleneck left in the software lifecycle is a human deciding what should be true. Everything downstream (design, implementation, verification, deployment) is a solved problem given sufficient structure. ### Axiom ii — Code is not text. Git tracks lines. Agents don't reason in lines. They reason in entities, invariants, and effects. Tooling that preserves a line-based worldview inherits its limits. We work one layer down. ### Axiom iii — The entity is the unit. A function, a class, a method, a config key. Not a character, not a line, not a file. Once your tools understand entities, most of what we call "merge conflicts" stops existing. ## Building Four things, all live: - **sem** — Semantic version control. Entity-level diffs, blame, and impact analysis on top of git. Ten languages via tree-sitter. See /sem or /sem.md. - **weave** — Entity-aware merge driver. Resolves the false conflicts git invents when independent edits share a file. See /weave or /weave.md. - **inspect** — Semantic code review. Entity graphs plus LLMs that read for meaning, not syntax. https://github.com/Ataraxy-Labs/inspect - **opensessions** — A tmux sidebar for managing coding-agent sessions. https://github.com/Ataraxy-Labs/opensessions ## Writing Essays on what comes after the IDE. Full index at /blogs or /blogs.md. ## Team Two people. The whole stack. See /team or /team.md. ## Colophon We are building the tools the next hundred million engineers will never need to learn. — Ataraxy Labs, founding memo ## Contact rohan@ataraxy-labs.com · https://github.com/ataraxy-labs --- # sem (/sem) --- title: "sem — Semantic Version Control" product: "sem" license: "MIT" --- # sem Semantic version control. Entity-level diffs on top of Git. Instead of "line 43 changed", sem tells you "function validateToken was added in src/auth.ts". ## Example ``` sem diff ┌─ src/auth/login.ts ────────────────────────────────── │ │ ⊕ function validateToken [added] │ ∆ function authenticateUser [modified] │ ⊖ function legacyAuth [deleted] │ └────────────────────────────────────────────────────── ┌─ config/database.yml ───────────────────────────────── │ │ ∆ property production.pool_size [modified] │ - 5 │ + 20 │ └────────────────────────────────────────────────────── Summary: 1 added, 1 modified, 1 deleted across 2 files ``` ## Install ``` npm install -g @ataraxy-labs/sem ``` Or run directly: ``` npx @ataraxy-labs/sem diff ``` ## Usage Works in any Git repo. No setup required. ``` # Semantic diff of working changes sem diff # Staged changes only sem diff --staged # Specific commit sem diff --commit abc1234 # Commit range sem diff --from HEAD~5 --to HEAD # JSON output (for AI agents, CI pipelines) sem diff --format json # Semantic commit history sem log -n 5 # SQL queries against stored changes sem init sem diff --store sem query "SELECT entity_type, entity_name, change_type FROM changes" ``` ## What it parses | Format | Extensions | Entities | | ---------- | -------------------------- | ---------------------------------------------- | | TypeScript | .ts .tsx | functions, classes, interfaces, types, enums | | JavaScript | .js .jsx .mjs .cjs | functions, classes, variables | | Python | .py | functions, classes, decorated definitions | | Go | .go | functions, methods, types, vars, consts | | Rust | .rs | functions, structs, enums, impls, traits, mods | | JSON | .json | properties, objects (RFC 6901 paths) | | YAML | .yml .yaml | sections, properties (dot paths) | | TOML | .toml | sections, properties | | CSV | .csv .tsv | rows (first column as identity) | | Markdown | .md .mdx | heading-based sections | Everything else falls back to chunk-based diffing. ## How matching works Three-phase entity matching: 1. **Exact ID match**: same entity in before/after → modified or unchanged. 2. **Content hash match**: same content, different name → renamed or moved. 3. **Fuzzy similarity**: >80% token overlap → probable rename. This means sem detects renames and moves in addition to adds and deletes. ## JSON output ``` sem diff --format json ``` ```json { "summary": { "fileCount": 2, "added": 1, "modified": 1, "deleted": 1, "total": 3 }, "changes": [ { "entityId": "src/auth.ts::function::validateToken", "changeType": "added", "entityType": "function", "entityName": "validateToken", "filePath": "src/auth.ts" } ] } ``` ## SQL queries ``` sem init sem log --store sem query "SELECT change_type, count(*) as n FROM changes GROUP BY change_type" ``` ``` change_type │ n ───────────────────────────────── added │ 29 deleted │ 2 modified │ 7 ``` ## Architecture - **tree-sitter** (native) for code parsing. Not WASM. - **better-sqlite3** for storage. WAL mode, fast transactions. - **simple-git** for Git operations. - Plugin system. Add your own parsers. ## Links - Source: https://github.com/Ataraxy-Labs/sem - Technical deep dive: /blogs/code-is-not-text or /blogs/code-is-not-text.md - License: MIT --- # weave (/weave) --- title: "weave — Entity-Level Semantic Merge" product: "weave" license: "MIT" --- # weave The Git merge driver for a world where agents write most of the code. Entity-level semantic merge driver for Git. Resolves false conflicts that Git's line-based merge creates when multiple agents (or humans) edit the same file on different branches. ## The problem Git merges by comparing **lines**. When two branches both add code to the same file, even to completely different functions, Git sees overlapping line ranges and declares a conflict: ``` <<<<<<< HEAD export function validateToken(token: string): boolean { return token.length > 0 && token.startsWith("sk-"); } ======= export function formatDate(date: Date): string { return date.toISOString().split('T')[0]; } >>>>>>> feature-branch ``` These are completely independent changes. There's no real conflict. But someone has to manually resolve it anyway. This happens constantly when multiple AI agents work on the same codebase. Agent A adds a function, Agent B adds a different function to the same file, and Git halts everything for a human to intervene. ## How weave fixes this Weave replaces Git's line-based merge with **entity-level merge**. Instead of diffing lines, it: 1. Parses all three versions (base, ours, theirs) into semantic entities (functions, classes, JSON keys, etc.) using tree-sitter. 2. Matches entities across versions by identity (name + type + scope). 3. Merges at the entity level: - Different entities changed → auto-resolved, no conflict. - Same entity changed by both → attempts intra-entity merge, conflicts only if truly incompatible. - One side modifies, other deletes → flags a meaningful conflict. The same scenario above? Weave merges it cleanly with zero conflicts. Both functions end up in the output. ## Weave vs Git merge | Scenario | Git (line-based) | Weave (entity-level) | | ---------------------------------------------------------- | ---------------------------- | --------------------------------------------------- | | Two agents add different functions to same file | CONFLICT | Auto-resolved | | Agent A modifies foo(), Agent B adds bar() | CONFLICT (adjacent lines) | Auto-resolved | | Both agents modify the same function differently | CONFLICT | CONFLICT (with entity-level context) | | One agent modifies, other deletes same function | CONFLICT (cryptic diff) | CONFLICT: function 'validateToken' (modified/deleted)| | Both agents add identical function | CONFLICT | Auto-resolved (identical content detected) | | Different JSON keys modified | CONFLICT | Auto-resolved | The key difference: Git produces false conflicts on independent changes because they happen to be in the same file. Weave only conflicts on actual semantic collisions, when two branches change the same entity incompatibly. ## Conflict markers When a real conflict occurs, weave gives you context that Git doesn't: ``` <<<<<<< ours — function `process` (both modified) export function process(data: any) { return JSON.stringify(data); } ======= export function process(data: any) { return data.toUpperCase(); } >>>>>>> theirs — function `process` (both modified) ``` You immediately know: what entity conflicted, what type it is, and why it conflicted. ## Supported languages TypeScript, JavaScript, Python, Go, Rust, JSON, YAML, TOML, Markdown. Falls back to standard line-level merge for unsupported file types. ## Setup ``` # Install brew install ataraxy-labs/tap/weave # In your repo: weave setup # Or manually: git config merge.weave.name "Entity-level semantic merge" git config merge.weave.driver "/path/to/weave-driver %O %A %B %L %P" echo "*.ts *.tsx *.js *.py *.go *.rs *.json *.yaml *.toml *.md merge=weave" >> .gitattributes ``` Then use Git normally. `git merge` will use weave automatically for configured file types. ## Preview Dry-run a merge to see what weave would do: ``` weave-cli preview feature-branch ``` ``` src/utils.ts — auto-resolved unchanged: 2, added-ours: 1, added-theirs: 1 src/api.ts — 1 conflict(s) ✗ function `process`: both modified ✓ Merge would be clean (1 file(s) auto-resolved by weave) ``` ## Architecture ``` weave-core # Library: entity extraction, 3-way merge algorithm, reconstruction weave-driver # Git merge driver binary (called by git via %O %A %B %L %P) weave-cli # CLI: weave setup and weave preview weave-crdt # Automerge-backed CRDT coordination state weave-mcp # MCP server (9 tools for AI agent integration) ``` Uses sem-core for entity extraction via tree-sitter grammars. ## How it works ``` base / \ ours theirs \ / weave merge ``` 1. **Parse** all three versions into semantic entities via tree-sitter. 2. **Extract regions**: alternating entity and interstitial (imports, whitespace) segments. 3. **Match entities** across versions by ID (file:type:name:parent). 4. **Resolve** each entity: one-side-only changes win, both-changed attempts intra-entity 3-way merge. 5. **Reconstruct** file from merged regions, preserving ours-side ordering. 6. **Fallback** to line-level merge for files >1MB, binary files, or unsupported types. ## Links - Source: https://github.com/Ataraxy-Labs/weave - Technical deep dive: /blogs/what-if-merges-understood-code or /blogs/what-if-merges-understood-code.md - License: MIT --- # Team (/team) --- title: "Team — Ataraxy Labs" --- # Team Two people. The whole stack. Ataraxy Labs is a two-person company. We write everything: compilers, merge drivers, MCP servers, documentation, this website. ## № 01 — Rohan Sharma Bulldozer. https://therohansharma.com/ ## № 02 — M Palanikannan Prodbreaker. https://www.palanikannan.com/ ## Hiring We're not hiring. If you disagree, write anyway: rohan@ataraxy-labs.com. --- # Community (/community) --- title: "Community — Ataraxy Labs" --- # Community Voices from the field. Notes, reactions, and quiet approvals from practitioners using sem, weave, and the rest of the stack in anger. ## On sem > Remember Weave, the entity-level git merge tool? Same team just shipped Sem: semantic version control on Git. Instead of 'line 43 changed' you get 'function validateToken added.' Entity-level diffs, blame, impact analysis. 16 langs via tree-sitter. — Zoltan (@zoltansoon) · https://x.com/zoltansoon/status/2030631503198031905 > git tells you 'line 43 changed'. sem tells you 'function validateToken was added in src/auth.ts'. entity-level diffs on top of git. also does impact analysis, dependency graphs, and entity-level blame. this is how code review should work — Anandu (@BFRAnandu13) · https://x.com/BFRAnandu13/status/2030622474011070657 > you need to check this out. this has SO many applications, from build optimizations to CI / CD, to LLMs. i have no doubt that this, or a project like it, will become the go-to in the future — merlin (@merlindru) · https://x.com/merlindru/status/2030277627626320173 > Not exactly what you asked for but you really really really gotta check this one out. Semantic diffs — merlin (@merlindru) · https://x.com/merlindru/status/2035093698308956193 > いいね、振り切ってる。Every tool in software development was designed for human hands. We're done building for human hands. — Mako (@fulore) · https://x.com/fulore/status/2039969629628739756 > 構文解釈したgit代替commandかな。sem diffを実行すると対象ファイルの言語構文を解釈した上で差分がある関数名を提示してくれたり。diff以外にblame, graph, impactなどが用意されてる。 — matsuu (@matsuu) · https://x.com/matsuu/status/2033143895547351235 > すごく良さそう!AI以前もほぼ無意識にこの程度のレビューで十分だと思ってたけど、今はなおさらだと思う — jackchuka (@jackchuka) · https://x.com/jackchuka/status/2040034543374385281 > Git diff está oficialmente muerto. En vez de escupirte 300 líneas para que adivines qué cambió... te dice la verdad: Función login() fue modificada. Clase UserService renombrada. Método validateToken() se movió. — Erick (@ErickSky) · https://x.com/ErickSky/status/2039507180739506354 > Another really cool one built on top of a different abstraction from the same team — Oliver Beavers (@oliverbeavers) · https://x.com/oliverbeavers/status/2037214929720107410 > if i never had to write 'this code hasn't changed, i just moved it' comments on my own prs again i'd be a happy bunny — jenna (@jjenzz) · https://x.com/jjenzz/status/2030660623814611089 > Okay, I took a look. This is freaking awesome. — Lacy (@lacybuilds) · https://x.com/lacybuilds/status/2030392092007006632 > Crazy no one ever thought about building this before. Insanely useful! — Parth S. (@savss624) · https://x.com/savss624/status/2030347730372186175 > This is some cool shit — Allison (@allisonology) · https://x.com/allisonology/status/2030299109538627748 > I've wished for something like this — tmuxvim (@tmuxvim) · https://x.com/tmuxvim/status/2030354499596902575 ## On inspect > Inspect does semantic code review using entity graphs + LLMs – it understands what your code *means*, not just what it says. Most linters catch syntax. This catches logic. — Gustavo Salami (@gustavosalami) · https://x.com/gustavosalami/status/2043230165522673919 > annotation-led review is the future. I wonder if you'd consider incorporating something like Inspect — Oliver Beavers (@oliverbeavers) · https://x.com/oliverbeavers/status/2036063959267016740 ## On opensessions > If you use tmux daily and have recently been using coding agents, this project might be worth checking out. A tmux sidebar that can synchronize and manage the status and sessions of different coding agents. — Jintao Zhang (@aiandcloud) · https://x.com/aiandcloud/status/2041518659714379786 > I just gave opensessions a spin after vibe-slopping my own solution – amazing work — Nimrod Gutman (@theguti) · https://x.com/theguti/status/2043999528156639351 > Tried cmux/conductor/superset/etc, the random bugs are really annoying. I've completely abandoned them for tmux plugins. Using opensessions. — Micro 小熊猫 (@xxm459259) · https://x.com/xxm459259/status/2042147729007341837 --- # Manifesto (/manifesto) --- title: "Manifesto — Ataraxy Labs" --- # Your code is alive. A nervous system. Pain receptors. A surgeon. An immune system. ## The diagnosis Every tool in software development was designed for human hands. Git tracks lines because humans read lines. IDEs highlight characters because humans scan characters. Merge conflicts read "line 42 conflicts with line 43" because that's the unit a human reviewer can hold in their head. Agents don't read that way. They reason about entities, invariants, and effects. Giving an agent git-flavored tooling is like asking a surgeon to operate with oven mitts on. ## The stack - **sem** extracts the entities. Functions, classes, methods, config keys. The nervous system. - **inspect** is the surgeon. Semantic review on the entity graph. It catches what linters miss because linters read characters. - **weave** is the immune system. It merges at the entity level so independent edits don't manufacture conflicts out of nothing. - **opensessions** is the operating room. A tmux sidebar for orchestrating the agents doing the work. - **agent** is the practitioner. Dispatched with sem, inspect, and weave. Makes the fix, opens the PR, moves on. ## The claim We're done building for human hands. The next hundred million engineers will never learn what a merge conflict looks like. They'll query a graph, not grep a file. They'll watch an agent ship a change and read the entity-level diff in a commit message that was written by a machine for a machine. The infrastructure for that world is what we build. Ataraxy Labs. The SDLC Singularity. rohan@ataraxy-labs.com. --- # Writing index (/blogs) --- title: "Writing — Ataraxy Labs" --- # Writing Essays from Ataraxy Labs on agent-native software, semantic version control, entity-level merges, and the unit of code. ## Patch Theory for Entities *September 2026 · 4 min read* Version control has been trying to acquire a theory for twenty years, and it keeps almost working. Merge becomes provable when you stop treating a file as a sequence and start treating it as a map. Read: /blogs/patch-theory-for-entities · Markdown: /blogs/patch-theory-for-entities.md ## Stop Grepping, Ask the Compiler *April 2026 · 3 min read* When you change a function, the compiler already knows everything about it, and yet agents ignore all of that and go grepping instead. Read: /blogs/stop-grepping · Markdown: /blogs/stop-grepping.md ## Code is not text. *February 2026 · 4 min read* Git is one of the greatest pieces of software ever written. It tracks text files brilliantly. But code has structure that text doesn't, and there's a lot you can do once your tools understand that. Read: /blogs/code-is-not-text · Markdown: /blogs/code-is-not-text.md ## The Entity *February 2026 · 5 min read* Every tool needs a unit of analysis, and text editors settled on characters while git settled on lines and compilers on tokens. We think the right unit for code intelligence is the entity. Read: /blogs/the-entity · Markdown: /blogs/the-entity.md ## What if Merges Understood Your Code? *February 2026 · 4 min read* Git's three-way merge is one of the most elegant algorithms in everyday use. It works on lines of text, which means it's occasionally too conservative about what counts as a conflict. Read: /blogs/what-if-merges-understood-code · Markdown: /blogs/what-if-merges-understood-code.md --- # Patch Theory for Entities (/blogs/patch-theory-for-entities) --- title: "Patch Theory for Entities" slug: patch-theory-for-entities date: "September 2026" read_time: "4 min read" word_count: 961 excerpt: "Version control has been trying to acquire a theory for twenty years, and it keeps almost working. Merge becomes provable when you stop treating a file as a sequence and start treating it as a map." filed_under: ["Merge theory","Version control","Formal methods"] --- # Patch Theory for Entities Version control has been trying to acquire a theory for twenty years, and it keeps almost working. Darcs shipped one in 2005 and it was never proven sound. Jacobson later gave it an algebraic footing with inverse semigroups, and Mimram and Di Giusto gave the whole idea a category-theoretic treatment where a merge is a pushout, which is what Pijul is built on. The mathematics is good. The problem is what it has to be a theory of. A patch to a sequence of lines is defined by position. Insert a line at index 12 and every later patch that mentions index 12 now means something different. Two edits a human would call obviously independent do not commute, because both are stated in coordinates the other one moved. Every line-based patch theory spends most of its machinery reconstructing intent that the representation destroyed. > Git conflicts when Alice adds a parameter to `process_payment` and Bob adds logging to `validate_order`. Nothing about those changes interacts. They were written close together, and *closeness is the only thing git can see.* ## One change to the model Let `N` be a set of stable entity names, meaning functions, classes and methods addressed by identity rather than position, and let `C` be their possible contents. A repository state becomes a finite partial map. ``` s : N ⇀ C ``` A patch is a set of primitive operations, each targeting one name. ``` add(n, c) applicable when n ∉ dom(s) del(n) applicable when n ∈ dom(s) mod(n, c → c') applicable when s(n) = c ``` Each is a partial invertible map on states, so patches form a groupoid, the same structure Jacobson found in Darcs. Nothing here is new mathematics. What is new is that operations are keyed by name instead of position, and that single change does the work, because two patches touching different names now commute by definition rather than after a normalization pass. ## Conflicts become decidable Given a base `b` and two patches out of it, the merge is the pushout of that span, meaning the smallest state containing both changes that commits to nothing neither side asked for. **THEOREM A.** If the names touched by two patches do not overlap, the pushout exists and equals the union of the patches applied to the base. **THEOREM B.** The pushout fails to exist precisely when the two patches touch a common name and assign it different content. That second one is the whole conflict condition. It is decidable, checkable in time linear in the size of the patches, and there is no heuristic and no threshold to tune. Unlike "the changed line ranges overlap", disjointness of names survives formatting, reordering and unrelated edits elsewhere in the file. To make merge total rather than partial, extend contents with an explicit conflict value, `C^ = C ∪ { conflict(base, ours, theirs) }`. The merge then always exists and is computed key by key. Because each key is an independent bounded join relative to the base, and products of semilattices are semilattices, idempotence, commutativity and a unit all fall out of the structure instead of needing separate proofs. The same shape buys something else. A finite map with a per-key join is a map-CRDT, so Shapiro's strong eventual consistency result applies directly, and there is already a machine-checked proof of exactly this shape in Isabelle by Gomes and Kleppmann. So a single three-way merge is correct by the pushout argument, and any number of agents editing concurrently converge by the semilattice one. The entity model is where both apply cleanly at once. ## The honest boundary None of this proves that merging two edits *inside the same function body* is correct. That residual is ordinary text merge and is not provable in general, so the real theorem is a reduction rather than a total result. > Entity theory reduces whole-repository merge to a provably sound, convergent, name-keyed algebra, plus a per-entity content merge left as an *abstract parameter.* That is weaker than "we proved merge" and it is the claim that is actually true. It is also more useful than it sounds, because it confines everything unprovable to a single function body rather than letting it range over a whole file. ## What this looks like in practice The most interesting case turns out to be where the right answer is to refuse. When both sides add different decorators to the same Python or TypeScript function, decorator application is function composition, so the stacking order changes behaviour. Putting `@cache` outside `@auth` serves cached responses without ever running the authentication check. There is no correct order to pick, so [weave](https://github.com/Ataraxy-Labs/weave) conflicts rather than inventing one, and we changed our own benchmark to stop scoring that refusal as a failure. Annotations in Java and C# are unordered metadata, so those still merge by set union. The part that has not worked is on the reading side. Per operation, asking [sem](https://github.com/Ataraxy-Labs/sem) for a function plus its callers costs far fewer tokens than grepping and reading files. That did not survive contact with an agent loop. In a small three-armed comparison on real tasks, the structural arm burned more tokens than plain file tools on one run, and solved fewer tasks on another. The sample is too small to conclude anything, but a per-operation reduction is plainly not the same as a session-level win, and we have measured one and not the other. ## What is open Formalizing the model and the two theorems in Lean or Isabelle, so the core is machine-checked rather than argued in prose. The CRDT half can be instantiated from existing work and the inner merge stays abstract. The part we are most confident about is the smallest. Choosing names over positions as the unit of change turns merge from a heuristic into a structure where a conflict has a definition, and two independent proofs apply to the same object. Everything after that is implementation, and implementation is allowed to be wrong in ways the model is not. --- # Stop Grepping, Ask the Compiler (/blogs/stop-grepping) --- title: "Stop Grepping, Ask the Compiler" slug: stop-grepping date: "April 2026" read_time: "3 min read" word_count: 920 excerpt: "When you change a function, the compiler already knows everything about it, and yet agents ignore all of that and go grepping instead." filed_under: ["Code intelligence","Agent systems","LSP"] --- # Stop Grepping, Ask the Compiler When you change a function, the compiler already knows everything about it. Where it lives, what calls it, what types flow through it, what breaks if you touch its signature. It built this map the last time it ran. It's sitting right there. But agents almost never reach for it, and go grepping instead. They grep for the function name, read some files, grep again with a different pattern, read more files, and repeat. Each round costs tokens and latency. *k* rounds of search to answer a question the compiler could answer in one. With *n* files in a codebase, grepping is O(n) per query. You scan everything for string matches when what you want is a graph traversal. Like reading every page in a library to find a phone number when there's a phone book on the front desk. > The compiler already did the hard work. Every symbol, every reference, every type — resolved. Why make agents *rediscover* it, one grep at a time? Why do agents grep? Because that's the tool they were given, and most agent frameworks hand you nothing beyond a file system and a text search. What agents actually need is structural, which is to say not which files contain the string `validateToken` but what calls it and what breaks if it changes. Those are graph questions rather than text questions. Tree-sitter turns out to be a surprisingly good middle path. It parses many languages with the same interface, works on broken code, and gives you the structural skeleton: functions, classes, imports, call relationships. Enough to build a dependency graph. A dependency graph can answer the questions agents actually ask. What depends on this function? What's the blast radius of this change? Which tests cover this code? Every one of those is a graph traversal, and none of them need grepping at all. Grepping returns text matches where a dependency graph returns relationships. Grep for `validateToken` and you get every file that mentions it: tests, comments, string literals, unrelated functions with similar names. The graph gives you exactly the callers and nothing else. Agents pay for noise with tokens. For a human, scanning grep results and skipping junk takes seconds. For an agent, every line of junk is real cost against a hard context limit. --- # Code is not text. (/blogs/code-is-not-text) --- title: "Code is not text." slug: code-is-not-text date: "February 2026" read_time: "4 min read" word_count: 1247 excerpt: "Git is one of the greatest pieces of software ever written. It tracks text files brilliantly. But code has structure that text doesn't, and there's a lot you can do once your tools understand that." filed_under: ["Version control","Code intelligence","Agent systems"] --- # Code is not text. Git is one of the greatest pieces of software ever written. The content-addressable object model, the DAG of commits, the branching system that makes parallel work feel natural. It solved distributed version control so thoroughly that nobody seriously tries to replace it anymore, and for good reason. When people complain about git, they're usually complaining about its CLI, not its architecture. The architecture is brilliant. But git was designed to track text files, and source code, while stored as text, has structure that plain text doesn't. A Python file isn't just a sequence of lines. It's a collection of functions and classes, each with defined inputs and outputs, connected to other functions and classes in other files through import statements and function calls. Git doesn't know any of this, and it was never supposed to. That wasn't the problem git set out to solve. But it means there's a layer of understanding that's missing from the tools we use every day. Consider what happens when a diff is expressed in lines versus entities. A typical file has L lines but only E entities, where E is much smaller than L, often by an order of magnitude. A file with 300 lines might contain 15 functions. When someone changes a few of those functions, git reports the diff in terms of L: you see some number of lines added, removed, or modified, grouped by file. But the actual semantic content of the change, the thing you need to understand in order to review it, is proportional to E. **CLAIM 1.2.** The signal-to-noise ratio of a line-level diff is bounded above by E/L — for most source files, a small number. > The ratio of signal to noise in a line-level diff is roughly *E / L* — and for most files that's a small number. ## What is the semantic gap? This is especially important for AI agents, and understanding why requires thinking about how agents process code. An agent reviewing a pull request pays a cost proportional to the number of tokens it has to read. Line-level diffs are expensive: every changed line, every context line, every reformatted line costs tokens. But the number of decisions the agent actually needs to make is proportional to E, the number of changed entities. If you feed the agent a line diff, it spends most of its token budget on noise. If you feed it an entity diff, it spends almost all of its budget on signal. The difference is not marginal, and in a codebase where L/E is 20 you're asking the agent to do 20× the work for the same amount of understanding. That's the gap we set out to fill with [sem](https://github.com/Ataraxy-Labs/sem). It sits on top of git and adds a layer that understands the structure of code. Instead of seeing a file as a sequence of lines, sem sees it as a collection of entities: functions, classes, methods. ## The dependency graph Each entity gets a structural hash computed from its AST rather than its text, so two versions of a function that look different but do the same thing produce the same hash. Reformatting, renaming a local variable and adding a comment all leave the hash untouched, so only changes to the actual logic register as changes. > An agent with the entity graph focuses on *E + D* — everything else is noise the compiler has already answered. But the most important thing sem adds, and the thing that matters most for agents, is the dependency graph. Because sem understands entities, it can build a cross-file graph of which functions call which other functions, across the entire codebase. And once you have that graph, you can answer a question that no amount of LLM reasoning can reliably answer: if I change this function, what else might break? We originally built sem because we needed exactly this for our own agents. But it turns out that what agents need and what humans need are the same thing, and probably always have been. Both agents and humans have limited attention, and both want to know what changed, whether it was real or cosmetic, and what it affects. Code has always had structure while our version control tools have only ever tracked text, and there is room for a layer in between that bridges the gap. --- # The Entity (/blogs/the-entity) --- title: "The Entity" slug: the-entity date: "February 2026" read_time: "5 min read" word_count: 1520 excerpt: "Every tool needs a unit of analysis, and text editors settled on characters while git settled on lines and compilers on tokens. We think the right unit for code intelligence is the entity." filed_under: ["Code intelligence","Architecture","Primitives"] --- # The Entity Every tool that works with code has to choose a unit of analysis, and text editors work in characters while git works in lines and compilers work in tokens and AST nodes. Each of these is the right choice for what that tool does. But when you want to do higher-level things with code, things like understanding what changed, figuring out what depends on what, merging parallel edits, or deciding what to review, you need a different unit. An entity is a function, a class, or a method, and deliberately nothing else. Not a file, not a line, not an AST node, not a module. The reason this particular granularity is the right one isn't arbitrary, and it's worth understanding why, because a lot of the power of entity-level tooling comes from properties that only hold at this specific level of abstraction. **DEFINITION 1.1.** An entity is the smallest unit of code with a name, defined inputs, defined outputs, and an identity that persists across versions. Start by thinking about what makes a good unit of analysis for code. You want something that is self-contained: it has a clear boundary, a name, defined inputs, and defined outputs. You want something that is independently meaningful: you can understand what it does without reading everything around it. You want something that maps to how people actually think about code: when a developer says "I changed the payment logic," they're pointing at something, and you want your unit to be that thing. > The entity is the *Goldilocks* unit: not too big, not too small, just right for ownership, merging, and independent reasoning. Functions satisfy all of these properties. A function has a name, a signature, a body. You can read a function and understand what it does. You can talk about a function in conversation and your colleague knows exactly what you mean. Functions call other functions, forming a dependency graph that tells you how changes propagate through a codebase. Classes satisfy these properties too, as do methods within classes, which are essentially functions with an implicit receiver. Now consider the alternatives and why they don't work as well. Files are too coarse to be useful, since a single file might contain ten unrelated functions, and if you treat the file as your unit, you lose the ability to distinguish between them. Two developers editing different functions in the same file look like they're in conflict, even though they're working on completely independent things. Lines have the opposite problem, because a single line of code has no independent meaning and is only ever a fragment of a larger thought. If you diff at the line level, you can see that something changed, but you can't tell what it means without reading the surrounding context. Lines also don't have dependencies. For agents specifically, the entity is the right unit because it matches the granularity at which agents naturally work. When an agent modifies code it doesn't think in lines, it thinks in terms of changing this function to handle a new edge case and updating that one to call it with the new parameter. Those are entity-level operations. There's also a coordination argument. When multiple agents work on the same codebase, they need a way to avoid stepping on each other. The entity is the natural unit of coordination because it's the smallest unit that can be independently owned. An agent can claim a function, work on it, and merge its changes with a guarantee that no other agent's work will conflict, as long as no other agent claimed the same function. --- # What if Merges Understood Your Code? (/blogs/what-if-merges-understood-code) --- title: "What if Merges Understood Your Code?" slug: what-if-merges-understood-code date: "February 2026" read_time: "4 min read" word_count: 1380 excerpt: "Git's three-way merge is one of the most elegant algorithms in everyday use. It works on lines of text, which means it's occasionally too conservative about what counts as a conflict." filed_under: ["Version control","Agent coordination","Merge theory"] --- # What if Merges Understood Your Code? Git's three-way merge is one of the most elegant algorithms in everyday software engineering. Take the common ancestor of two branches, compare what each side changed, and combine the results. It's fast, predictable, and it works remarkably well considering it has no idea what the content it's merging actually means. But every developer has had the experience of getting a merge conflict that didn't feel like a real conflict. Alice adds a parameter to `process_payment()` while Bob adds logging to `validate_order()`. These are completely independent changes to different functions that don't share any logic or state. But because the two functions happen to sit next to each other in the same file, git's merge algorithm sees that the surrounding context lines overlap and conservatively reports a conflict. The reason this happens is that git's merge is, by design, working at the line level. It can see that two branches both modified lines near each other, but it can't see that those lines belong to different functions and therefore can't possibly interfere. > If the set of entities each side touched don't overlap, the merge is *confluent.* Order doesn't matter — you always converge. To understand why this matters increasingly over time, think about it in terms of how conflict probability scales. If you have K workers (humans or agents) making changes to a codebase, and a file contains E independent entities, the probability of a true conflict follows birthday-paradox-style scaling: it's roughly proportional to K²/E. As K grows, the gap between true conflicts and reported conflicts widens — quadratically. This is where agents make the problem acute. A human developer can pause, look at a false conflict, realize the two changes don't interact, and resolve it in a minute. An agent can't do this nearly as cleanly, because a merge conflict breaks its workflow and every false one is a point where the pipeline stalls or degrades. So we built [Weave](https://github.com/Ataraxy-Labs/weave) as a git merge driver. It plugs directly into git's existing merge pipeline, so you don't change your workflow at all and still use git, still use branches, and still merge the way you always have. The only difference is that when git encounters a file that both branches modified, Weave steps in and parses all three versions of the file into structural entities using tree-sitter: functions, classes, methods, imports. It matches entities across versions by name, and then merges each entity independently. For agents, confluence is the critical property, because it lets an agent know before it starts working whether its changes will merge cleanly. If an agent is about to edit entity X, and it can check that no other agent is currently editing X, it has a mathematical guarantee that its work will merge. It doesn't need to hope, or retry, or call an LLM to resolve conflicts afterward.