Events live in git refs, not your working tree
Issues are an append-only event log under refs/grite/wal, CBOR-encoded, optionally Ed25519-signed. Your working tree stays clean. Code review never has to scroll past tracker noise.
Grite stores issues as an append-only event log inside git refs (refs/grite/wal), keeping your working tree pristine while enabling seamless multi-agent collaboration through deterministic CRDT-based conflict resolution. No servers. No databases. No merge conflicts. Just git.
$ curl -fsSL https://raw.githubusercontent.com/neul-labs/grite/main/install.sh | bash
~5ms
append an issue to the WAL
~10ms
list 1,000 issues from sled
~50ms
rebuild state from latest snapshot
10
languages with symbol extraction
Not an opinion — a different storage model. Everything below falls out of one decision: put the issues in git refs.
| Traditional trackers | grite | |
|---|---|---|
| Storage | External database | Git refs in your repo |
| Sync | API calls | git fetch / git push |
| Offline | Requires connectivity | Works entirely offline |
| Multi-agent | Rate limits, auth tokens | CRDT merge, no conflicts |
| Working tree | N/A | Completely clean |
| History | Audit logs (optional) | Immutable event log (built-in) |
| Agent-native | Bolted-on integrations | Designed for agents from day one |
A handful of well-understood primitives — git refs, sled, CRDTs, Ed25519 — composed in a way that makes issue tracking native to development instead of an external concern.
Issues are an append-only event log under refs/grite/wal, CBOR-encoded, optionally Ed25519-signed. Your working tree stays clean. Code review never has to scroll past tracker noise.
No API keys, no service accounts, no third-party uptime. Pull the WAL when you fetch, push it when you push. The CRDT merge is deterministic, so concurrent edits never produce conflicts.
grite init writes the standard discoverability file. Any AI agent that follows the convention finds grite immediately, with no configuration, and treats it as persistent memory across sessions.
Claim src/parser.rs for thirty minutes; any other agent that asks for the same lock sees it is taken and picks a different task. TTL leases mean a crashed agent never deadlocks the queue.
Rust, Python, TypeScript, JavaScript, Go, Java, C, C++, Ruby, Elixir. Agents can ask "what calls this function?" and create issues that quote the relevant code, not vague prose.
List 1,000 issues in ~10ms. Create one in ~5ms. The git WAL is truth; sled is the fast cache. Periodic snapshots rebuild state in ~50ms instead of replaying the entire log.
Task decomposition, multi-agent coordination, persistent memory. Agent A claims a refactor; Agent B sees the lock and picks something else. Memory issues survive across sessions and are visible to every future agent.
Offline issue tracking from inside the terminal. Open issues on a plane, sync when you land. Personal knowledge base of architectural decisions that travels with the repo.
Distributed coordination through the git remote you already use. No new infrastructure, no accounts to provision. Issues branch and merge alongside the code they describe.
Sensitive issues never leave your infrastructure. Ed25519 signatures provide cryptographic proof. The append-only WAL is tamper-evident — any modification breaks the hash chain.
Track deployment steps as a typed dependency DAG. Coordinate rollbacks with distributed locks. Store post-mortems with full context. Generate changelogs from closed issues between releases.
No project picker. No workflows to configure. No state that lives in a third party. One CLI, one log, one merge rule.
Three layers that separate storage, query, and interface. The WAL is truth; sled is the fast cache; the daemon is a performance optimisation, not a requirement.
+---------------------+ +----------------------+ +---------------------+
| Git WAL | --> | Materialized view | <-- | CLI / Daemon |
| refs/grite/wal | | sled database | | grite / grite-daemon|
| (source of truth) | | (fast queries) | | (user interface) |
+---------------------+ +----------------------+ +---------------------+
| | |
v v v
Append-only CRDT projection IPC via Unix
event log with LWW + set domain sockets
CBOR-encoded semantics (rkyv zero-copy) Every issue mutation is appended as a CBOR-encoded event, content-addressed by a 256-bit BLAKE2b hash. Optional Ed25519 signatures bind events to per-actor keys.
Embedded key-value store materialises current issue state from the WAL. CRDT projection with last-write-wins on scalars and commutative-set semantics on labels and links.
CLI works standalone. The daemon auto-spawns to keep the cache warm and serialise concurrent calls, and idle-shuts down after five minutes. flock prevents cross-process corruption.
Two real alternatives, picked because public facts let us draw fair rows. No straw men.
GitHub Issues is the default for public projects and the inbound surface most teams cannot replace. Grite is the internal task graph you reach for when you want offline-first, repo-local state and CRDT merge for parallel agents.
Linear is a polished hosted tracker with strong product workflow. Grite is a different architecture entirely — your issues live in the repo, sync with git, and require zero accounts. Pick on storage model, not on UI taste.
Beads is the most-cited git-native tracker for AI agents, backed by an embedded Dolt database. Grite stores the same kind of issues as pure git refs with a CRDT log — no database, git as the only dependency. Pick on substrate.
Inside your git repository, in refs under refs/grite/wal. The WAL is an append-only, CBOR-encoded event log. A local sled database holds a materialised view of issue state for fast queries. The sled cache can be deleted at any time and rebuilt from the WAL — git refs are the only source of truth.
No server. The daemon (grite-daemon) is optional and only exists to keep the materialised view warm and serialise concurrent CLI calls. The CLI works standalone and auto-spawns the daemon when it would help. The daemon idle-shuts down after five minutes by default.
Grite uses CRDT semantics — last-write-wins on scalar fields, commutative-set semantics on labels and dependencies. Any two valid WALs can merge, the result is the same regardless of merge order, and no edit is silently dropped.
The WAL is content-addressed: every EventId is a BLAKE2b hash of the event payload. Modifying any byte invalidates the chain. Optional Ed25519 signatures bind each event to a per-actor key, giving non-repudiable provenance for compliance and audit.
It can. For repo-local work it is faster, offline-first, and agent-native. Teams that need a public bug reporting surface often keep GitHub Issues for inbound reports and use grite for the internal task graph. Grite can export to JSON, Markdown, or CSV to feed downstream systems.
Tested with 100,000+ events and 10,000+ issues. Sled gives O(1) lookups by issue ID. Materialised-view rebuild is O(delta) past the most recent snapshot. The WAL appends at 1,000+ events per second locally.
curl -fsSL ... | bash is the one-line installer. Homebrew, cargo, npm (grite-cli), pip (grite-cli), gem (grite-cli), and chocolatey are all supported. Pre-built binaries for Linux, macOS (Intel/ARM/Universal), and Windows are on the releases page. The only runtime dependency is git 2.38 or later.
Grite is MIT licensed, has stable APIs across six Rust crates, and is shipped via crates.io, npm, PyPI, RubyGems, Homebrew, and Chocolatey. The architecture has been engineered around well-understood primitives — git refs, sled, CRDTs, Ed25519 — rather than novel ones.
One install, one init, zero accounts. The next time you git push, your issues go too.
Three lines to first issue
$ brew install neul-labs/tap/grite $ grite init $ grite issue create --title "..."