rtk-ai
grit
Rust

Git for AI agents — zero merge conflicts, any number of parallel agents, same codebase

Last updated Jul 3, 2026
96
Stars
10
Forks
1
Issues
+2
Stars/day
Attention Score
45
Language breakdown
Rust 59.4%
Shell 17.7%
TypeScript 11.8%
Python 11.0%
HTML 0.1%
Files click to expand
README

grit — Coordination layer for parallel AI agents

Zero merge conflicts, any number of parallel agents, same codebase.

CI License Stars

Translations: Francais · Deutsch · Espanol · Portugues · Italiano · Nederlands · 日本語 · 中文 · 한국어 · Русский · العربية · हिन्दी


The Problem

When multiple AI agents work in parallel on the same codebase, git breaks. Agents edit different functions in the same file, and git sees conflicting hunks at the line level. The merge fails — all the agent's work is thrown away.

The more agents, the worse it gets:

RAW GIT                         GRIT
Agents  Features Lost  Work Wasted    Features Lost  Work Wasted
─────── ────────────── ────────────   ────────────── ────────────
  10       14/20          70%            0/20            0%
  20       15/20          75%            0/20            0%
  30       25/30          83%            0/30            0%
  50       45/50          90%            0/50            0%

With 50 agents and raw git, 90% of all work is thrown away to merge conflicts. Each failed agent must be re-invoked — more API cost, more time, more waste.

The Solution

Grit locks at the function level (AST), not the file level (lines). Different functions in the same file never conflict.

Agent-1: claim login()          → Granted
  Agent-2: claim login()          → Blocked (held by Agent-1)
  Agent-2: claim logout()         → Granted ← same file, no conflict

Agent-1: done → merge + release Agent-2: done → merge + release Result: 0 conflicts, 0 wasted work

How It Works

┌──────────┐    ┌──────────┐    ┌──────────┐
  │ 1. CLAIM │───▶│ 2. WORK  │───▶│ 3. DONE  │
  │          │    │          │    │          │
  │ Lock AST │    │ Parallel │    │ Rebase + │
  │ symbols  │    │ worktrees│    │ Merge    │
  └──────────┘    └──────────┘    └──────────┘
       │               │               │
       ▼               ▼               ▼
  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ SQLite,  │    │ .grit/   │    │ Serial   │
  │ Azure or │    │ worktrees│    │ file lock│
  │ S3 store │    │ /agent-N │    │ → merge  │
  └──────────┘    └──────────┘    └──────────┘
  • Claim — agent locks specific functions. Other agents are blocked from editing those functions.
  • Work — each agent works in its own git worktree. Full isolation, true parallelism.
  • Done — auto-commit, rebase on main, merge. Merges are serialized via file lock to prevent index.lock races.

Supported Languages

Grit uses tree-sitter to parse ASTs. 13 languages supported:

| Language | Symbols Extracted | |----------|-------------------| | TypeScript / TSX | functions, classes, methods, interfaces, types, enums | | JavaScript / JSX | functions, classes, methods | | Rust | functions, structs, enums, traits, impls, types | | Python | functions, classes | | Go | functions, methods, types | | Java | methods, classes, interfaces, enums | | C# | methods, classes, interfaces, structs, enums, namespaces | | C | functions, structs, enums, typedefs | | C++ | functions, classes, structs, enums, namespaces | | Ruby | methods, classes, modules | | PHP | functions, methods, classes, interfaces, traits, enums | | Swift | functions, classes, structs, enums, protocols | | Kotlin | functions, classes, objects, interfaces |

Backends

Local (default)

SQLite WAL for single-machine coordination. Zero setup.

grit config set-local

Azure Blob Storage (recommended for teams)

Native API with atomic locking (If-None-Match: *) and free events via Azure Event Grid. Every claim and release fires a BlobCreated/BlobDeleted event — no polling needed.

grit config set-azure \
  --account <storage-account> \
  --access-key <key> \
  --container grit-locks

Tested with 50 agents in parallel on Azure Blob Storage:

Agents │ Merges │ Conflicts │ Locks left │ Azure blobs left │ Time
───────┼────────┼───────────┼────────────┼──────────────────┼──────
    10 │     20 │         0 │          0 │                0 │   6s
    20 │     40 │         0 │          0 │                0 │   6s
    30 │     54 │         0 │          0 │                0 │  11s
    50 │     54 │         0 │          0 │                0 │  11s
    50 │     76 │         0 │          0 │                0 │  24s  (pi-calc, 44 symbols)

S3-Compatible (AWS, R2, MinIO)

Works with any S3-compatible provider. Atomic locking via conditional PUT on AWS S3 and Cloudflare R2.

grit config set-s3 \
  --bucket my-bucket \
  --endpoint https://... \
  --region auto

| Provider | Atomic Locking | Events | |----------|:---:|:---:| | Azure Blob | If-None-Match (native) | Event Grid (free, 100K/mo) | | AWS S3 | If-None-Match (native) | S3 Event Notifications | | Cloudflare R2 | If-None-Match (native) | — | | MinIO | GET-then-PUT (fallback) | — |

Install

cargo install --git https://github.com/rtk-ai/grit

Quick Start

cd your-project
grit init                    # Parse AST, build symbol index + dependency graph

Agent claims functions before editing

grit claim -a agent-1 -i "add validation" \ src/auth.ts::validateToken \ src/auth.ts::refreshToken

Agent works in isolated worktree: .grit/worktrees/agent-1/

... edit files ...

Finish: auto-commit, rebase, merge, release locks

grit done -a agent-1

Commands

Core Workflow

grit init                                    # Parse AST, build symbol + deps index
grit claim -a <agent> -i <intent> <syms...>  # Lock symbols + create worktree
grit done  -a <agent>                        # Merge + release locks
grit status                                  # Show active locks
grit symbols [--file <pattern>]              # List indexed symbols
grit plan -a <agent> -i <intent>             # Search symbols + show deps

Lock Modes

# Exclusive write lock (default)
grit claim -a agent-1 --mode write src/auth.ts::login

Shared read lock (multiple readers allowed)

grit claim -a agent-2 --mode read src/auth.ts::login

Dependency-aware: auto-lock callees as read

grit claim -a agent-1 --with-deps src/auth.ts::login

→ Granted: login (write), validateToken (read), hashPassword (read)

Queue (contested symbols)

# If blocked, join queue instead of failing
grit claim -a agent-2 --queue src/auth.ts::login

→ Queued (position 1). Auto-granted when agent-1 releases.

grit queue list # Show all queued agents grit queue cancel -a agent-2 # Leave the queue

Auto-Assignment

# Auto-pick a free symbol from matching files
grit assign -a agent-1 -i "add logging" --file src/auth

→ Assigned: src/auth.ts::logout

Session Workflow

grit session start auth-refactor     # Create branch grit/auth-refactor

... agents claim, work, done ...

grit session pr # Push branch + create GitHub PR grit session end # Cleanup, back to base branch

Monitoring & Events

grit watch                           # Real-time event stream (Unix socket)
grit watch --poll 5                  # Polling mode (for S3/distributed backends)
grit gc                              # Clean expired locks
grit heartbeat -a <agent> --ttl 900  # Refresh lock TTL

On Azure, events are automatic via Event Grid — every claim fires BlobCreated, every release fires BlobDeleted. Agents can subscribe to these events for real-time coordination without polling.

Backend Configuration

grit config show                                                          # Current config
grit config set-local                                                     # SQLite WAL (default)
grit config set-azure --account <name> --access-key <key> --container <c> # Azure Blob
grit config set-s3 --bucket <name> --endpoint <url> --region <r>          # S3/R2/MinIO

Architecture

┌──────────────────────────────────────────┐
│              your git repo               │
├──────────────────────────────────────────┤
│  .grit/                                  │
│  ├── registry.db    (SQLite WAL)         │  ← symbols + locks + deps + queue
│  ├── config.json                         │  ← backend config
│  ├── room.sock      (Unix socket)        │  ← real-time events (local)
│  ├── merge.lock     (file lock)          │  ← serializes git merges
│  └── worktrees/                          │
│      ├── agent-1/   (git worktree)       │  ← isolated working dir
│      ├── agent-2/                        │
│      └── agent-N/                        │
├──────────────────────────────────────────┤
│  Backends:                               │
│  ├── Local: SQLite WAL (default)         │
│  ├── Azure Blob Storage (native)         │  ← atomic + Event Grid
│  ├── AWS S3 (conditional PUT)            │
│  ├── Cloudflare R2                       │
│  └── MinIO (self-hosted)                 │
└──────────────────────────────────────────┘

Troubleshooting

grit done reports "main worktree has uncommitted changes" — the merge is skipped on purpose to avoid corrupting the repo. Commit or stash the changes in your main checkout, then run grit done again. The agent branch agent/<name> is kept intact, so no work is lost.

grit claim says a symbol "is not in the registry" — the symbol was never indexed. Run grit symbols to list indexed symbols, or re-run grit init if the codebase changed since the last scan.

Relative-path dependencies break inside .grit/worktrees/ — a worktree lives a few directories below the repo root, so a Cargo/npm dependency declared with a relative path (e.g. path = "../sibling") resolves to the wrong place. Symlink the dependency next to the worktrees directory, or use an absolute path in the manifest.

Benchmarks

Benchmark: grit vs git

Tested across 3 projects (ts-api, pi-calc, rust-service), 1 to 50 agents, 3 rounds each:

RAW GIT                         GRIT
Agents  Merge Failures  Work Wasted    Merge Failures  Work Wasted
─────── ──────────────  ───────────    ──────────────  ───────────
     1       0%             0%              0%             0%
     2      50%            50%              0%             0%
     5      80%            80%              0%             0%
    10      80%            80%              0%             0%
    20      75%            75%              0%             0%
    30      73%            73%              0%             0%
    50      51%            51%              0%             0%
With 10 agents: git throws away 80% of all work. Grit throws away 0%.

Run benchmarks

# Feature throughput sweep (10, 20, 30, 50 agents)
./scripts/throughput/bench.sh --sweep

Synthetic merge conflict test

./scripts/synthetic/bench.sh --agents 50 --rounds 5

Sweep across projects

./scripts/sweep/bench.sh --agents "10 20 30 50" --projects "ts-api rust-service py-ml"

Real AI agents (Claude / Gemini)

./scripts/ai-agents/bench.sh --agents 10 --provider claude ./scripts/ai-agents/bench.sh --agents 20 --provider gemini

Part of the RTK AI Ecosystem

| Project | Description | |---------|-------------| | rtk | Token-optimized CLI proxy (60-90% savings) | | icm | Infinite Context Memory for AI agents | | vox | Cross-platform TTS with MCP server | | grit | Coordination layer for parallel AI agents |

License

Licensed under the Apache License, Version 2.0.

Copyright (c) 2025-2026 RTK AI. All rights reserved.

🔗 More in this category

© 2026 GitRepoTrend · rtk-ai/grit · Updated daily from GitHub