Designing for AI agents as first-class issue authors
When we sketched the first version of grite, we did the exercise that every issue-tracker designer does: write down the cast of characters who would create, read, and edit issues. The list looked normal — engineers, PMs, support — and then there was a second list that nobody around the table could agree on the shape of: AI agents.
The honest read on the state of the world was that within twelve months, the agents would be writing more issues than the humans. We could either retrofit a tracker designed for humans, the way hosted trackers were starting to do, or we could assume the agent population from the start and design around it. We went with the second option, and almost every interesting design decision in grite traces back to that one choice.
What agents actually need from a tracker
A useful framing exercise is to list the things an agent struggles with that a human does not. The list is short and unsurprising once you make it:
An agent has no memory across sessions. It starts each invocation as a blank slate. Whatever it learned in the last hour about your codebase is gone unless something persisted it.
An agent cannot ask its peers what they are working on. Without explicit coordination, two agents will start the same refactor and produce conflicting patches.
An agent cannot read a web UI. It can drive one, but the cost is high and the failure modes are weird.
An agent does not have an identity by default. Without one, an audit trail cannot answer “which agent broke this.”
A tracker designed for agents should therefore be: persistent across sessions, queryable for what is in flight, scriptable end-to-end, and identity-aware. Grite is the answer if you take those four requirements seriously.
Persistent memory by way of the WAL
The substrate for persistence is the WAL itself. Every issue, every comment, every label, every lock acquisition becomes an event in refs/grite/wal. The events are CBOR-encoded, content-addressed by a 256-bit BLAKE2b hash, and optionally signed with an Ed25519 key bound to the agent’s actor identity. The sled materialized view rebuilds the current state of every issue from those events.
The implication for agent memory is that “what did I learn yesterday” is a query against the local materialized view. The pattern most teams adopt is the memory label. An agent finishing a task creates an issue with --label memory and a body that captures the architectural decision, the gotcha, or the constraint it discovered. The next agent that boots reads issues labelled memory as part of its initialization routine, and inherits the context of every prior agent that ran on the repo.
The reason this works where chat-context memory fails is that the WAL is shareable, durable, and bounded only by disk. A repo with a thousand memory issues uses about a megabyte of git ref storage. The agent does not have to make a network call to consult them. The human can read them too, in plain text, in the terminal.
Coordination through distributed locks
The second non-negotiable for agent-first design is coordination. If two agents start the same task, you lose. The simple version of the answer is a lock, but the operational version is more nuanced — you need locks that survive an agent crash, locks that other agents can see, and locks that the human in the loop can override.
Grite’s lock primitive lives under refs/grite/locks/. Acquiring a lock is grite lock acquire <resource> --ttl <seconds>. The TTL is a lease, not an absolute. If the agent dies, the lease expires and the next claimant succeeds. If the work runs long, the agent renews. Other agents see the lock through grite lock list, and humans can break a stuck lease with grite lock release --force when something is genuinely wedged.
The behaviour we tuned hardest is the conflict signal. When an agent attempts to acquire a held lock, the JSON output includes the holder’s actor ID, the lease expiry, and the issue ID associated with the held work. That gives the requesting agent enough information to either wait, pick a different task, or post a comment on the blocking issue. We have seen agents organically learn the pattern of “if blocked, propose a related task,” which is a behaviour we did not write into the harness — it emerged because the signal was rich enough.
Identity that survives
Every actor in grite has a 128-bit randomly generated ActorId. When grite init runs, it provisions one for the local actor and stashes the public key in the repo-level config. From that point on, every event the actor produces can be signed and verifiably attributed.
For agents this matters because it gives provenance to the audit trail. “Which agent created this issue” is answerable, and the signature is content-addressed against the WAL — a malicious agent cannot rewrite history without invalidating the hash chain. Compliance teams have started to ask for exactly this property as agent-driven changes show up in production codebases, and grite already has it because it was a first-day requirement.
The actor identity also means agent telemetry has a clean shape. “How many issues did agent-7f1e close this week” is a one-line grite issue list --closed --actor 7f1e --since 7d. Compare that to the experience of pulling agent attribution out of a hosted tracker, which usually involves cross-referencing API keys against deployment metadata.
Machine-readability without an API layer
Most “AI-friendly” hosted trackers ship an API and call it done. The cost of that approach is the entire surface of API ergonomics: auth tokens, rate limits, schema drift, pagination quirks, partial failures during long sessions. Agents are not great at any of those.
Grite avoids the whole class of problems by being shell-shaped. Every command supports --json, and the JSON schemas are documented and stable. An agent that wants to know what issues exist runs grite issue list --json. An agent that wants to update an issue runs grite issue update <id> --label foo --json. There is no token, no rate, no schema versioning to defend against, no second source of truth to keep in sync. The CLI is the API, and the JSON is the contract.
The corollary nobody warned us about is that this shape composes far better with agent harnesses than a REST API does. An agent’s tool layer typically already speaks shell. Adding grite is one tool definition. Adding a hosted tracker is a small piece of glue code per endpoint, with auth and error handling for each.
AGENTS.md as the discovery layer
The detail that has produced the most surprised reactions is the smallest. When you run grite init in a repo, grite writes a file called AGENTS.md to the project root. The file documents how to use grite as a memory system, what the lock primitives look like, and which labels matter.
The point of AGENTS.md is that the major AI coding agents already look for a file by that name on startup. The convention predates grite; we are riding the convention. If a Claude or Codex-style agent boots in a grite-using repo, it reads AGENTS.md and discovers grite without any explicit prompting from the human.
That is, in practice, the single most important property we shipped. An agent that opens a new project does not need a system prompt mentioning grite. The repo introduces itself. By the time the agent is ready to act, it knows there is a memory layer, what the actor identity is, and how to claim a lock before starting work. The whole onboarding ceremony is one read of one file.
What we still want to add
The agent-side roadmap has two things on it that we think are worth telegraphing.
The first is richer “blocked-by” hints. Right now, an agent that sees a held lock has to decide on its own what to do. We are exploring a lightweight intent annotation on locks — what is the holder trying to accomplish — so the requesting agent can make smarter decisions, such as “extend the existing issue rather than create a redundant one.”
The second is a built-in subscription primitive. The WAL is the source of truth, and a long-running agent harness wants to be notified when it changes. The pub/sub interface is on the daemon roadmap; it will plug into the existing IPC layer without changing the on-disk format.
Both are additive, both are agent-first, and neither requires a server. The bet from day one is that you can build a tracker for agents and humans together by treating agents as a first-class population. Everything that has gone well about grite has come back to that single bet.