DEV Community

Cover image for What is Lonca? Version control for AI coding agents (Lonca series, part 0)
Selçuk GÜRAL
Selçuk GÜRAL

Posted on Originally published at selcukgural.com AI-assisted

What is Lonca? Version control for AI coding agents (Lonca series, part 0)

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.

Diagram of Lonca, version control for AI agents: an agent proposes and a human approves; the lonca daemon, the only writer, decides with decide(), signs, appends to the log and only then applies it to the Git repository; a sandboxed verifier runs build and test; after git push, lonca-audit replays every decision on the remote.
Agents propose; the daemon, the only writer, decides, signs and records.

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.sh or cargo 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 use lonca mcp today.
  • 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:

brew tap selcukgural/lonca && brew install lonca
# or: curl -fsSL https://selcukgural.github.io/lonca/install.sh | sh
# or: cargo install --locked lonca lonca-audit
Enter fullscreen mode Exit fullscreen mode

First run:

lonca daemon &                       # the gatekeeper
lonca human keygen ayse              # or --secure-enclave, --security-key
lonca init demo --import ~/src/myproject
lonca session start --repo demo --agent claude --paths 'src/**' \
        --task T-142 --ttl 2h --workspace ~/ws/claude-1 --harness claude-code
lonca doctor                         # what a first run trips over
cd ~/ws/claude-1 && claude
Enter fullscreen mode Exit fullscreen mode

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:

  1. One writer and a pure decide(): why there is no AI, network or randomness in the decision
  2. Symbol leases and the structural merge: agents working in parallel on one file
  3. Taint: content read from outside, and prompt injection
  4. The operation log and lonca-audit: how you prove a decision afterwards
  5. Human signatures: the Secure Enclave and FIDO keys
  6. 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.

This post was first published on my blog.

Top comments (0)