AgentGit is a version control system for repositories that people, coding agents and CI all write to.
A change lands only when the repository's policy says it may, and the policy is checked in the same transaction that moves the branch, so nothing can change between "checked" and "merged". Test results are signed and tied to the exact tree they ran on. Every agent run has its own identity, and every decision ends up in an audit log you can verify. The core that stores, merges and recovers never calls a language model; anything smart sits on top and can only propose.
It is alpha software: status and limits are below, and nobody but its authors has run it in production.
A person, two agents and a CI service share one stream. The output is trimmed from
examples/quickstart.sh, which CI runs on every push and compares line by line with this block.
$ ag integrate prop_6eed… # as agent:refactor-bot — an agent tries to land code on its own
Denied by policy; the stream was not changed:
- actor not allowed to integrate: agents may not integrate unless agent_autonomy.auto_integrate is on …
$ ag integrate prop_6eed… # as user:alice
Blocked (policy v1); the stream was not changed:
- check 'tests' has no trusted passing attestation for this exact tree
- approvals (default): 0 of 1 required
- agent-authored change has no signed provenance
- exclusive lease on 'src/**' held by agent:refactor-bot#run_8f78… (stale_or_missing_token)
candidate tree: 315f74d45183c9e7…
$ ag validate run prop_6eed… --check tests --key ci -- cargo test # as service:ci
check 'tests' PASSED on tree 315f74d45183 (policy v1); attestation att_0f1a… signed by service:ci
$ ag proposal review prop_6eed… --approve # as user:bob
$ ag integrate prop_6eed… --fencing-token 1 # as user:alice
Integrated (merge): stream is now at 793a03b6da69 (version 3, was 70e31c72a4d0), 1 file(s) changed.
$ ag preview prop_2b19… # a concurrent edit to the same line
strategy: Merge (algorithm ag-merge/3+ag-diff/1)
conflict: src/main.rs (content conflict (1 region(s))) # exit code 4 — the stream was not touched
Every refusal says what is missing. Exit code 3 means blocked (supply what is missing and run it again), 4 means refused.
You need Rust 1.89 or newer and a C compiler (SQLite is built in). Linux, macOS and Windows are built and tested in CI;
the sandbox and ag-worker are Linux-only (Windows).
git clone https://github.com/Paffin/AgentGit && cd AgentGit
cargo install --path crates/ag-cli # installs the `ag` binaryOr take the pre-release v0.2.0-rc.2: archives for
Linux and macOS (x86_64 and aarch64) with ag, ag-server, ag-worker and ag-mcp, SHA256SUMS, SBOMs, and multi-arch
images ghcr.io/paffin/agentgit-server and agentgit-cli.
curl -fsSL https://raw.githubusercontent.com/Paffin/AgentGit/main/scripts/install.sh | sh -s -- --version 0.2.0-rc.2
docker pull ghcr.io/paffin/agentgit-cli:0.2.0-rc.2--version is needed while only pre-releases exist. Checked on the published files: checksums, the quick start and the
server flow below, install.sh, and the attestations of both images (gh attestation verify, by the owner). Not
verified: the archive attestations, the macOS and aarch64 archives outside CI, the Homebrew formula.
Install options has the details.
mkdir demo && cd demo
ag init --namespace me/demo # creates .ag/ and the stream "main"
echo "# demo" > README.md
ag snapshot -m "first" # record the directory (not yet visible to others)
ag propose -t "Initial import" # verify, publish and open a proposal
ag integrate <proposal-id> # move "main" atomically; any unique id prefix works
ag logNext, add a policy, start an agent, or run the whole story with
./examples/quickstart.sh. The full walkthrough is Getting started.
ag-server dev # data directory, administrator, demo repository, a sign-in link
ag login http://127.0.0.1:8080 --token-file ./ag-dev-data/dev/token
ag clone http://127.0.0.1:8080/demo/welcome # edit, `ag snapshot`, `ag push -t "my change"`, `ag explain` if refusedag-server dev prints a link that signs you in to the Web UI and the exact commands above. It is an evaluation mode
(loopback only, plain HTTP, an 8-hour credential), not a deployment. It is on main and not in the v0.2.0-rc.2
archives: until the next tag, Getting started has the same
start on rc.2 in a few more lines.
cargo install --path crates/ag-server
export AG_BOOTSTRAP_TOKEN=$(openssl rand -hex 32) # the first administrator's credential
ag-server admin --data-dir ./ag-data create-repo acme/web
ag-server admin --data-dir ./ag-data grant --subject user:alice --repo 'acme/*' --role admin
export AG_TOKEN=$(ag-server admin --data-dir ./ag-data mint --subject user:alice --ttl 86400 | tail -n 1)
ag-server serve --data-dir ./ag-data & # 127.0.0.1:8080, gRPC + HTTP/JSON
ag clone http://127.0.0.1:8080/acme/web web && cd web # then edit, `ag snapshot`, `ag push -t "my change"`The server speaks one protocol, AGWP v1, over gRPC and HTTP/JSON on a single port, and serves the Web UI on it. Compose, Kubernetes, TLS and PostgreSQL with S3 are covered in Deployment.
- Publishes a change in one verified transaction and moves the stream head by compare-and-swap. A crash at any step leaves exactly one outcome; failures are injected at every protocol step in the tests.
- Merges with a pure, versioned function of base, ours and theirs. Conflicts are typed results reported before anything changes, and a file renamed on one side and edited on the other merges cleanly.
- Binds validation to the candidate tree. An attestation names the tree, the policy version and the environment, and is signed by an issuer the policy trusts. When the stream moves, the old result stops counting.
- Keeps a policy per stream: required checks, approvals bound to the reviewed head, protected paths, and an autonomy envelope that says which paths, and how many files, an agent may land without a person.
- Coordinates agents: an identity per run, tasks, soft and exclusive leases with fencing tokens, conflict prediction and an ordered integration queue.
- Runs untrusted checks in
ag-workerinside a sandbox (rootless namespaces or a container) and signs the result. - Records an append-only reflog and a hash-chained audit log;
ag verifychecks the whole repository. - Imports from and exports to Git with identical tree SHAs, and works fully offline.
- Ships a Web UI, TypeScript and Python SDKs, an MCP server that exposes AgentGit to an agent as tools, and a Go agent platform that can propose changes but never integrate them.
GitHub, GitLab and Bitbucket are mature hosting platforms with a great deal AgentGit does not have: issue tracking, hosted CI, security scanning, permissions at scale, support. The table covers only the question AgentGit is built around: how a change lands when several untrusted actors write to one codebase. Cells about the platforms describe their public documentation; the page linked below has the sources, the access date and the much longer list of what they do better.
| GitHub | GitLab | Bitbucket | AgentGit | |
|---|---|---|---|---|
| Unit of review | pull request | merge request | pull request | proposal |
| Where merge rules are enforced | the platform: branch protection and rulesets | the platform: protected branches, approval rules, push rules (several need Premium) | the platform: branch permissions, merge checks (enforced on Premium in Cloud) | the stream's policy, evaluated in the transaction that moves the head |
| A passing check is bound to the exact tree that lands | in the merge queue, which tests a temporary merge of the queue; otherwise to a commit | with merged results pipelines and merge trains (Premium); otherwise to a pipeline | required builds on the head commit; merge queues build a merge result (paid plans, Pipelines) | always: a signed attestation names the tree, policy version and environment |
| Identity of automated actors | accounts, GitHub Apps, tokens | service accounts, access tokens | accounts, tokens | an identity per agent and per run; credentials can be bound to one run |
| Policy-bound autonomy for agents | built from branch rules and bot permissions | built from the same pieces | built from the same pieces | built in: allowed paths and a file limit per stream |
| Tamper-evident audit | an audit log with export; the docs make no integrity claim | audit events (Ultimate); the docs make no integrity claim | an audit log; not compared | hash-chained, checked by ag audit and ag verify |
| Self-contained and offline | hosted; Enterprise Server for self-managed | SaaS or self-managed | Cloud or Data Center | local mode needs no server; the server is one binary |
| Ecosystem | very large | very large, CI and security built in | large, Jira and Pipelines | small: CLI, SDKs (unpublished), MCP, Web UI |
| Maturity | very high | very high | very high | alpha |
The full comparison, including Git, Gerrit and Jujutsu: AgentGit compared.
A new user starts on a home page that says what needs attention, with plain labels (the AgentGit word is in a tooltip),
blockers that come with their fix as a button, guided flows to start a repository or give an agent work, rules presets
instead of raw JSON, and editing a file and proposing it from the browser. These are in main, not in the rc.2 archives.
What is still missing is on the roadmap.
A live board of runs, leases, tasks and the merge queue, with four independent verdicts per proposal. These are real screenshots of the UI running against a real server, captured by the end-to-end suite.
A proposal: four verdicts, what blocks it, the diff |
Policy: versioned, append-only, with diffs |
Blame: line-level, follows renames |
flowchart LR
W["workspace<br/>snapshots"] -->|propose| P["publish<br/>verify every object,<br/>register in ONE transaction"]
P --> Q["proposal<br/>reviews bound to the head"]
Q -->|integrate| C["candidate<br/>fast-forward or<br/>deterministic merge"]
C --> G{"policy, in the<br/>committing transaction"}
G -->|allowed| S[("stream head<br/>compare-and-swap<br/>+ reflog + audit")]
G -->|blocked / denied| Q
C -.->|conflict| W
classDef step fill:#e8eeff,stroke:#5b6cff,color:#1b2150
classDef gate fill:#fff4d6,stroke:#c99a1e,color:#4a3508
classDef done fill:#dcf5e8,stroke:#1f9d67,color:#0f3d2e
class W,P,Q,C step
class G gate
class S done
A proposal has four verdicts. They are independent: none implies another, and each changes on its own.
| Verdict | Question | Decided by | Changes when |
|---|---|---|---|
| Mergeable | Is there one unambiguous result tree? | the merge engine (ag preview) |
a change on either side leaves no single result |
| Validated | Did trusted checks pass on that tree? | signed attestations | the candidate tree or the policy changes |
| Approved | Did enough eligible people approve that head? | reviews and policy | the author pushes again, or the policy's bar moves |
| Integrated | Was the stream updated atomically? | one compare-and-swap transaction | never; it is a fact in history |
Three trust boundaries matter more than the boxes. The core decides without a model, a clock or randomness. The engine runs inside the server, so policy is enforced where untrusted clients connect. Untrusted code runs only in a separate execution plane, which can report a result but never decides whether it counts. Read more in Concepts, the architecture overview and publication and integration.
Each row names a test in this repository. More than 1,000 Rust tests run in CI, together with the SDK, Web UI and
orchestrator suites against a real ag-server, fuzzing, coverage and mutation gates (Testing).
| Guarantee | Test |
|---|---|
| A crash at any step of publication or integration recovers to exactly one update | crash_at_every_step_recovers_to_exactly_one_integration |
| No lost update under parallel integrators | concurrent_integrations_never_lose_an_update |
| A lost response never causes a double apply | idempotent_replay_and_unknown_outcome_recovery |
| A check on an old candidate is not reused after the stream moves | attestation_cannot_be_reused_after_the_stream_moves |
| A stale lock holder cannot land into a scope someone else now holds | fencing_tokens_are_strictly_increasing_and_reject_stale_holders |
| Byte formats match an independent Python implementation | tests/conformance/ |
| Git history round-trips with identical tree SHAs | history_survives_a_round_trip_with_identical_git_trees |
| Tampering with the audit log or objects is detected | audit_chain_detects_tampering |
The threat model and its known limits are in Security.
| Start | Getting started, tutorials, concepts, FAQ, comparison |
| Guides | agents, policy, validation, workers, remote, history, Git bridge |
| Clients | Web UI, SDKs, MCP, orchestrator |
| Reference | CLI, configuration, AGWP v1, OpenAPI, object formats |
| Operations | deployment, high availability, observability, backup, hardening, troubleshooting |
| Design | architecture, ADRs, ADR traceability, security, sandbox |
The docs are checked in CI: the CLI reference is generated from the binary, tutorial commands are run against real
binaries, and scripts/check_docs.py verifies links, test names, ag commands and AG_* variables. The site builds with
mkdocs build --strict and deploys to GitHub Pages from main.
AgentGit is alpha. The core and the guarantees above are implemented and tested, and so is the platform around it. It has not been run in production by anyone but its authors, and there has been no external security audit. The full list is in ROADMAP.md and CHANGELOG.md; the ones that decide whether you can use it today:
- Local mode trusts the local user. Identities are labels, and anyone who can write
.ag/can bypass policy; tampering is detectable withag verify, not prevented. Against clients you do not control, runag-server. - Several server replicas on one PostgreSQL and one S3 bucket are tested with real processes in CI. A PostgreSQL
failover, mixed versions during a rolling upgrade, load, and the Kubernetes
haoverlay on a real cluster are not proven (high availability). - Credentials can be bound to one agent run (ADR-0010), but that is opt-in
per client; acting on another agent's run needs
agent.operate, which a plain writer does not have. Fencing tokens for job claims are optional per request (ADR-0012). - Only a pre-release is published (
v0.2.0-rc.2: GitHub release and images on GHCR). No stable release, and no crates.io, npm or PyPI package; the 21agentgit-<x>crates are only dry-run (releasing). Metadata schema 3 is not readable by older builds: upgrade replicas new build first. ag validate runis not a sandbox. Untrusted code goes throughag-worker, whose sandbox shares the host kernel. Verified against real Docker and Podman and cgroup v2; not verified for microVMs, Windows (the worker refuses to run) or macOS beyond a limits-only fallback (sandbox).- PostgreSQL and S3 are tested against a real PostgreSQL and SeaweedFS, not against Amazon S3, MinIO, Ceph or R2.
- Trees are flat manifests, measured at 100,000 files (ADR-0006). Performance numbers come from one shared 4-vCPU VM and are not targets (engine, server); PostgreSQL, S3, TLS and multi-replica throughput are not measured. The decoded-tree cache and the 3 durable commits per integration were measured on the memory and disk backends only.
- No history rewriting, tags, submodules or LFS; the Git bridge reports what it cannot carry.
- The Web UI is tested in Chromium, Firefox and WebKit; OIDC only against Keycloak. There has been no screen-reader pass.
ag-mcpwas not run inside real hosts. The SDKs are unpublished. - The nightly fuzz and weekly mutation jobs have not run on GitHub yet.
Reasonable today: a team and its agents on one machine, one server or a few replicas, with CI-gated workflows, or
experimenting with policy-bound autonomy. Not yet: hosting mutually untrusting tenants, or being the only copy of data you
cannot lose. Keep ag backup copies and a Git mirror.
See CONTRIBUTING.md. Changes to formats, hashing, merge semantics or the publication protocol start with an ADR. Report security issues as described in SECURITY.md. Everyone taking part follows the Code of Conduct.
Apache License 2.0, see LICENSE. Copyright 2026 The AgentGit Authors.



