For a while now I have been working on Lonca, a version control system for AI agents. This post starts a series about it. Later posts will take its parts one at a time; this first one only gives the overall picture: what Lonca is, which problem it tries to solve, and how much of that it does today, in version 0.2.3.
I will try not to oversell it. I will write down what works, and also what does not exist yet.
Lonca in short: version control for AI agents
Lonca is a version control system for repositories where several AI agents and a few humans work at the same time. It is written in Rust and it is open source (Apache-2.0).
It does not try to replace Git. The content stays plain Git: you can push to GitHub, and your Git tools keep working. What changes is everything around it: who may do what, how work done at the same time is merged, and how every operation is recorded and checked.
The name comes from the craft guilds of the Ottoman bazaar, the lonca: written rules, masters, journeymen and apprentices, and an inspection before goods reach the market. That is Lonca’s model too.
The problem it solves
Most days I run several coding agents on the same repository. The agents do their work well; the problem is the tooling around them. Git and platforms like GitHub assume that every writer is a person. With agents, that assumption breaks in three places:
- Permissions. An agent works with my token, shows up in the history under my name, and has every right I have. Even when its task is to fix one function, it can force-push, delete a branch or change the CI files. Nothing stands in between.
- Concurrency. Two agents working on the same file only find out about each other at merge time. Each is green on its own; together they are red.
- Accountability. When something goes wrong, I can’t answer the two questions that matter: what was this agent allowed to do, and did it do only that?
Lonca exists to answer these three.
How it works
The core idea is simple: agents never write to the repository directly, they propose. A single process on the machine, the Lonca daemon, is the repository’s only writer. It decides every request, signs the decision, appends it to an operation log kept inside the repository (refs/lonca/oplog), and only then applies it.

Four parts around the daemon
Four parts are built around that:
- Capabilities, not accounts. Every agent works in a session, and the session gets narrow rights that expire: which paths it may touch, which operations it may run, size limits. Rights can only narrow when they are handed to sub-agents. Revoking a session revokes everything derived from it. Unknown operations, scopes and paths are refused.
- Symbol leases and a structural merge queue. Agents lease the functions and types they edit, so several agents can work in parallel on different functions of the same file. When an agent proposes a change, it declares what it changed; Lonca computes what really changed with tree-sitter and refuses the proposal if the two don’t match. The merge queue merges changes symbol by symbol and runs the build and tests in a sandbox with no network access; trunk moves only after that.
- Taint. The tool the agent runs in (the harness; today that is Claude Code) reports every tool call to the daemon, and a proxy sees outbound connections. A session that reads outside content (a web page, an issue, another MCP server) counts as tainted: its changes need a human’s approval, and it may not touch build scripts, CI or lock files at all. This is the structural answer to prompt injection.
- A log anyone can replay. Every operation, whether allowed, denied or sent to a human, is in the log, and the log travels with the repository on
git push. The log is append-only; an undo (lonca undo) is a new, compensating operation. The independent auditor,lonca-audit, replays every decision from the start, recomputes every merge, and catches a forged entry even when it is signed with the daemon’s own key.
Human signatures, and no AI where integrity depends on it
Humans sign their own operations with their own keys. The key can live in the Mac’s Secure Enclave or on a FIDO security key; then every approval needs Touch ID or a touch. An agent running as your user can’t approve on your behalf.
There is no AI where integrity depends on it. The decision function decide(), the daemon and the auditor contain no AI, no network and no randomness. decide() is a pure function, and all of its inputs, time included, are in the log entry. Build and test results are recorded as evidence and never recomputed later. AI appears only as an optional advisor that helps a human during review, and it decides nothing.
Where it stands today
The current version is 0.2.3. Every phase of the design is implemented and tested. A log written by any 0.x release stays readable and auditable by every later release.
What it does today
- Full support for Claude Code. I build Lonca against Claude Code and try it live before every release. The hooks and Lonca’s MCP tools are ready as soon as a session starts.
- Symbol-level work in 13 languages. Rust, Python, TypeScript/TSX, JavaScript, C#, Go, Java, Kotlin, C, C++, Ruby, PHP and Swift. Markdown, TOML, JSON and YAML files are split into sections; other files are leased whole.
- macOS and Linux. Installed with Homebrew,
install.shorcargo install. - Tests. More than 1,800 tests, real sandbox and socket tests included. 45 acceptance criteria, run with the real binaries and real daemon processes, must pass before every release. Eight fuzz targets must also be green before every release.
Three levels of trust
How far you can trust what you see depends on how you run the agents. There are three levels:
| Mode | How agents run | Going around the store | Setup |
|---|---|---|---|
| Cooperative | As your user | Not prevented, but detected (hash chain, auditor). Every change needs a human’s approval. | None |
| Hardened | As your user; Claude Code’s hooks and sandbox are locked | Prevented: the daemon is a separate system user | An install script run as root |
| Isolated | Inside a container or an OS sandbox | Prevented | Your own container runtime |
What doesn’t exist yet, or is limited
- One machine. 0.x is for one developer with many agents. A team server is designed, not built.
- One real user. The only real project running on Lonca today is imece, and that is my project too.
- Other harnesses. Codex, Gemini CLI and OpenCode have profiles and run isolated under
lonca run, but their hooks are not wired up yet. IDE agents are planned; any client that speaks MCP can uselonca mcptoday. - The verifier’s limits. Resource limits hold for each process; a build or test command’s total disk, memory and (on macOS) process count are not bounded yet. So only verify commands you would run yourself. On Linux the sandbox needs
bubblewrap. - Signature changes. When a function’s signature changes, Lonca notices and asks for it to be declared, but it does not analyze the callers. Broken calls are caught by the tests in the merge queue.
- Redaction is logical. When a leaked secret is redacted, the daemon no longer hands out its content, but the object is not yet purged from Git history.
- Paths not yet exercised. Signing with a physical FIDO key has not been tried by the project yet. The AI advisor has only been tested against a fake API.
The full, current list is on Lonca’s site, under Limitations.
Who it is for, and how to try it
Right now Lonca is version control for AI agents on one developer’s machine. It is mostly for developers who run several coding agents on the same repository on their own machine and want to keep what those agents do under control. If you work with a single agent now and then, you probably don’t need it; Git and a good code review are enough.
Install:
First run:
From here the agent leases the symbols it edits and makes proposals. You see what is waiting with lonca pending, approve with lonca approve, undo with lonca undo when needed, and audit the log with lonca-audit verify. The step-by-step walk-through is in the quick start guide.
What comes next in the series
In the next posts I plan to explain each part on its own, together with why it was built that way:
- One writer and a pure
decide(): why there is no AI, network or randomness in the decision - Symbol leases and the structural merge: agents working in parallel on one file
- Taint: content read from outside, and prompt injection
- The operation log and
lonca-audit: how you prove a decision afterwards - Human signatures: the Secure Enclave and FIDO keys
- Lonca with Claude Code: a real working day
The order and the topics may change along the way. Every post of the series will be collected under the Lonca category.
One last note: I built Lonca with heavy help from Claude Code. The design and every decision are mine, and each one is written down with its reasons in docs/decisions.md.
The code is on GitHub, the documentation is on Lonca’s site. Questions and ideas go to Discussions, bugs to issues.