重构 Anthropic 源码控制系统:从 Git 迁移至为常在线 Agent 打造的 Scion
英文标题:ArticleOct 19, 2026Redesigning source control at AnthropicAs merges to Anthropic's monorepo grew from about 2,500 to more than 30,000 a day, source control became the biggest development bottleneck. Here is how the team built Scion, an in-house version control system designed for always-online agents, and migrated off git in five months.Claude Code (opens in new tab)
随着 Claude 在 Anthropic 内部实现自主循环研究与大规模编写代码,其 Monorepo(单一代码库)的日均合并次数在数月内从约 2,500 次暴增至 30,000 余次,原本为人类开发者规模设计的 Git 基础设施成为最大瓶颈。为此,Anthropic 自研了专为常在线 Agent 设计的分布式版本控制系统 Scion,并在五个月内完成彻底迁移。Scion 采用全线上、客户端/服务端非对称设计、无锁提交和三层缓存架构,消除了全量工作副本依赖并支持通过 API 高效交互。这一演进表明,随着 AI 辅助编码进入 Agent 时代,底层软件工程工具链正全面面临从「人类尺度」向「Agent 尺度」重构的必然趋势。
89.9 KB
45.8 KB
130.4 KB
65.0 KB
76.8 KB
143.9 KB
16.7 KB
中文
10 月 15 日更新:补充了为 Scion 中所用多项技术奠定基础的先行项目的更多细节。
在 Anthropic,编写代码已不再是构建系统或开展研究的瓶颈。Claude 能够自主进行研究循环的迭代、对复杂程序进行微调优化,并以我们前所未见的速度和规模从零开始构建新服务。如今,真正的瓶颈变成了所有专为人类开发者规模构建的工程基础设施:源码版本控制、构建系统以及 CI。
2026 年 5 月,Anthropic 平均每天合并约 2,500 次代码变更;而到了 9 月,我们每天合并的代码变更已超过 30,000 次。我们预计这种增长速度短期内不会放缓;合并代码的潜在需求几乎是无限的,我们消除的每一个瓶颈都会立即进一步推高我们产出的代码量。

2026 年 1 月至 9 月合并到我们 Monorepo 的日均变更数。
为了支撑这种增长,我们自主研发了一套名为 Scion 的内部版本控制系统,并在五个月内将 Monorepo 从 Git 完全迁移出来。在同一时期,我们还构建并上线了一套代码审查界面(名为 Antique)、代码搜索服务、丰富的源码控制 IAM(身份与访问管理)系统,以及管理与合入海量经审查代码的全新方式等。在本文中,我们将重点探讨 Scion 的构建过程。这是一个颇具启发性的案例研究:Claude 编写代码的能力,既是最初将我们推向这一困境的根源,也是我们能够迅速构建出一套高可用、可扩展系统来应对该问题的关键所在。
快速膨胀的 Monorepo
在探讨我们构建了什么之前,有必要先正视我们工作负载的特殊性。毫无疑问,Anthropic 使用 Claude 编写软件的强度远超几乎任何其他公司,因此我们往往是最先察觉到为人类规模构建的工具在何处开始捉襟见肘的团队。源码版本控制仅仅是其中一个例子。虽然我们预计短期内不会有很多机构遇到这些难题,但我们相信,其他使用 AI 编程工具的团队很快也会遭遇同样的压力点,这也是我们希望分享自身成果与经验的原因。
Git 是一个分布式系统:每一个 clone 都是一个完整且自包含的代码仓库,能够在完全离线的情况下计算 diff、读取历史记录和 blame、检出任意版本。对于绝大多数代码仓库而言,这是一种正确的设计,也是 Git 成为行业标准的重要原因。
然而,随着我们的 Monorepo 不断膨胀,它越来越无法适应这种设计范式。仅主分支(main)的历史记录就接近 100 GB,一个压缩后的工作副本也超过 25 GB。仅 CI 一项,我们每天执行的代码检出(checkout)次数就高达 2500 万次左右,这还没算上开发者环境、Agent 沙箱以及科研任务。如果直接按常规方式拉取,每天仅 Git 流量就将超过 600 PB。
Git 确实提供了一些用于处理仓库子集的工具,例如浅克隆(shallow clone)、稀疏检出(sparse checkout)以及 promisor remotes。除此之外,业界应对大型 Monorepo 还有一些标准解决方案,如内部 Git 镜像以及保存在对象存储中的仓库快照(seeds)。这些方法我们全部用过——在业务峰值期,我们运行了数百个内部 Git 镜像来分担负载。这确实为我们争取到了时间,但随着合并速率不断提升,它们的运维难度也越来越大。两次快照刷新之间,seeds 距离 main 分支顶部的差距越来越大;而在部分克隆上维持 diff 和 blame 等依赖历史记录的操作正常运行,也需要耗费越来越多的精力。

扩展 Git 检出的典型架构。
退一步来看,我们发现自己和大多数公司一样,将 Git 当作拥有单一权威副本的中心化系统来使用,但我们几乎所有的客户端本质上都是始终在线的 Agent 和作业任务。Git 那些在分布式、离线场景下表现优异的特性,反而随着仓库规模的扩大严重制约了我们的扩展能力。于是我们扪心自问:如果我们从一开始就基于「Agent 永远在线」这一事实来设计源码控制系统,它应该是什么样子?
Agent 尺度下的源码控制设计原则
在 Agent 编码时代,许多关于软件开发的传统假设都在发生变化。在构建 Scion 时,我们全面拥抱了这些变化,从而在几个核心原则上采取了与 Git 截然不同的设计方向。面向超大 Monorepo 的版本控制系统已有前人探索,最著名的当属 Google 的 Piper 和 Meta 的 Sapling,因此我们在构建 Scion 时充分借鉴了它们来之不易的经验教训。我们的设计原则如下:
客户端永远在线(Clients are always online)。 Git 假设客户端在离线状态下工作,因此需要仓库的完整副本。鉴于我们几乎所有的客户端都是 Agent 和自动化任务,我们将 Scion 的客户端和协议围绕一个「始终可达」的服务器进行设计,让客户端仅在需要时按需获取数据。
客户端与服务端非对称(Client-server asymmetry)。 在 Git 中,每个客户端都具备成为完整服务端的能力。而在 Scion 中,服务端负责回答文件历史与 blame 查询、创建 commit、执行 merge 与 rebase 等操作。客户端仅维护一个有限的本地对象缓存,在磁盘上组织工作副本文件,监控文件系统变动,并为用户提供与服务端交互的易用方式。客户端自身几乎不进行复杂计算,但作为交换,它在本地所需的数据量大幅减少。
功能完备的源码控制服务可赋能众多新型应用(A comprehensive source control service can power many novel applications)。 在 Git 中,CI 任务或工具若需查询仓库信息(例如某一行最后由谁修改、两个 commit 之间有何关联),必须在本地维护一份代码副本,或者寄希望于特定厂商的 API 能提供答案。而在 Scion 中,客户端使用的所有源码控制查询接口均通过 API 对外暴露,因此在很多情况下,任务根本不需要本地仓库。若没有这种低成本、编程式的源码控制访问能力,我们很多内部工具(例如自动化二分查找 bisect 和 revert 流水线)在大规模场景下根本无法实用落地。
一切必须水平可扩展(Everything must be horizontally scalable)。 在峰值时期,我们运行了数百个 Git 镜像,这极大地消耗了算力容量,且一旦仓库体积超过镜像的磁盘或内存上限,系统便难以为继。在 Scion 中,仓库数据是分布式存储的,每个组件都可以独立进行水平扩展;无论何处——哪怕在服务端——都不存在一份完整物化的仓库副本。这里没有类似 packfile(Git 的压缩对象包)的概念,因此无需进行仓库碎片整理等维护操作。
提交必须廉价、增量且无锁(Commits must be cheap, incremental, and lock-free)。 在 Git 中,你先在本地进行 commit,然后通过 push 分享你的工作。在 Scion 中,所有的 commit、rebase 或 merge 都直接在服务端发生,因此完全不需要 push,但这些操作的每一个都必须极为迅速。创建 commit 及更新其下游数据结构的开销,必须与该次变更的大小成比例,而非与整个仓库的总体规模成比例,否则服务端将不堪重负。Scion 的开发流程不鼓励使用 ref(指向 commit 的指针,如分支和标签,除 main 或发布分支外),因为让每台服务器都达成一致的全局状态本身就是一个潜伏的扩展性隐患。
工作副本是可选的,且原生设计为稀疏(The working copy is optional, and sparse by design)。 由于我们的 Monorepo 极为庞大,且每天需要为 CI 执行数千万次代码检出,我们希望尽可能避免完整的 checkout。在 Scion 中,例如一个需要计算某个 commit 与其 merge base 之间 diff 的 CI 任务,直接向服务端请求即可。写操作也是如此:许多写负载同样可以跳过 checkout,完全通过 API 进行操作。Scion 的协议以稀疏检出(仅包含客户端请求的目录)和虚拟化检出(按需动态物化文件)为核心,因此当某个任务确实需要在磁盘上落地文件时,客户端只需为其真正读取的内容买单。
Scion 的运行机制
理解这些原则在 Scion 的实际构建中是如何结合的会很有帮助。这些经验不仅适用于其他版本控制系统,更广泛地看,也能为软件开发生命周期的其他阶段提供参考。
数据结构
在 Scion 中,基本工作单元是一个「变更集」(changeset),它是预写日志(WAL)中的一条记录。Changeset 存储了你在 Git commit 中能见到的大部分信息。但 Git commit 存储的是指向整棵目录树的指针,而 Changeset 存储的则是相对于其第一父节点发生变化的文件列表,以及指向对象存储中压缩文件内容的基于内容寻址的指针。Changeset 在服务端创建,并可立即在全局范围内访问。

Scion 中变更集(Changeset)的形态。
这种结构使我们能够以极高的吞吐量接收 changeset,因为无需接收 packfile,不存在加锁或跨服务器协调,也不需要移动 ref 指针。Scion 在技术上确实支持 ref,但由于创建和拉取 commit 均不涉及 ref,因此移动 ref 仅仅是对单个 Spanner 行执行一次 CAS(比较并交换)操作,与创建 changeset 是完全解耦的独立过程。
由于 changeset 仅记录发生变更的内容,单靠它自身无法快速回答「谁最后编辑了某一行」或「哪些 commit 影响了某个文件」这类问题。为了解答这些疑问,Scion 会基于 changeset 构建额外的数据结构,包括用于文件 blame 和路径历史的专用结构,以及针对 commit 图的跳表(skip list)。我们将所有不直接属于 changeset 本身的数据统称为「派生数据」(derived data),并且全部通过一个通用机制进行计算。每种类型的派生数据均采用递归定义,因此某个 changeset 的派生数据值,直接由该 changeset 父节点对应的数值计算得来。
该机制带来了三大收益:第一,当引入新的数据结构能加快某项操作时,我们可以轻松增加新的派生数据类型;第二,对于每种类型,我们可以自由选择立即预计算还是延迟计算,从而避免物化不需要的数据;第三,由于客户端永远接触不到这些数据结构的内部实现细节,我们可以在完全不变更客户端的前提下对服务端结构进行优化。随着系统规模的增长,我们已多次新增派生数据类型,例如用于执行代码复制检测或基于路径的文件搜索的新索引。
扩展 Scion
一个小型 Scion 服务器集群对外提供满足客户端任何操作所需的源码控制 API,例如获取 changeset、计算 diff、查找 merge base 以及获取 blob 等。所有版本控制数据均采用内容寻址,因此数据一旦存储便不可更改,任何服务器都可以直接缓存,无需与其他节点协商确认。其结果是,这些服务器具备水平可扩展性,且极少需要节点间协同。它们本质上是一批大型缓存层,同时能够在运行时动态计算派生数据,并将结果写回 Spanner。
Scion 的众多使用者不再需要在本地维护自己的代码仓库。在过去,拉取和维护本地仓库对于需要进行版本查询(尤其是 commit 祖先关系和 blame)的 CI 任务或工具而言是一项沉重的维护负担。在迁移初期,在我们尚未拥有自己的客户端、仓库格式或协议之前,Scion 仅用于响应这些「元数据」查询。而获取文件内容与物化工作副本是数据密集度高得多的操作,需要专门的一套架构设计。
Scion 的 scn 客户端在几个关键维度上背离了 Git 的 fetch 协议,从而构建出一套相比 Git 服务端大幅降低 CPU 开销的高扩展性架构。Scion 的数据协商不会告知服务端客户端本地已经拥有什么;相反,它完全围绕客户端所请求的 tree 和 blob 展开。客户端从根 tree 开始,检查本地存储中缺失的 tree 并进行递归请求,随后对 blob 重复该过程。由于每个请求针对的都是不可变的特定对象,任何缓存层均可直接响应,其架构与传统的分层缓存高度相似。这一过程同时具备高效率和断点续传能力,因为传输过程中不存在单一数十 GB 的 packfile 响应。稀疏检出乃至虚拟化检出也无需特殊支持,因为客户端只需直接忽略那些不需要的 tree 即可。
在集群内部,客户端通过套接字与节点守护进程 scion-daemon 通信,该守护进程为整台物理节点统一缓存对象。我们的大多数节点都需要访问 Monorepo,而运行在同一节点上的任务往往会复用大部分相同对象。每个 daemon 从定期刷新的快照启动,随后仅与其所在区域的 tree 与 blob 缓存服务器(称为 scion-cache)通信。这些缓存服务器以 daemon 所需的磁盘格式直接从内存流式传输对象,因此无需耗费时间计算客户端缺失了哪些对象,也无需执行增量 delta 压缩。当缓存未命中时,再向权威的 scion-server 请求,由后者按需从 Spanner 或云存储中读取。
在这个协议中,scion-daemon、scion-cache 和 scion-server 响应完全相同的 RPC,因此客户端无需感知缓存拓扑。理论上任何层级都可以与其他层级通信,但我们严格执行分层限制以隔离故障域,防止区域级 scion-cache 故障导致流量直接击穿至上游的 scion-server 并引发全系统崩溃。

Scion 的检出架构。
该系统的每一层都保持了超过 99% 的缓存命中率,且不需要长时间运行的常驻连接。
English / 原文
Updated October 15 to include more detail on the projects that pioneered many of the techniques we use in Scion.
At Anthropic, coding is no longer the bottleneck to building systems or doing research. Claude is able to autonomously iterate on research loops, micro-optimize complex programs, and build new services from the ground up at a speed and scale we haven’t seen before. The bottleneck, now, is all of the developer infrastructure built for human scale: source control, builds, and CI.
In May 2026, Anthropic averaged around 2,500 code changes merged per day; as of September, we merged over 30,000 per day. We don’t expect this rate of growth to slow down anytime soon; the latent demand for merging code is practically infinite, and every bottleneck we remove immediately leads to a further increase in the amount of code we produce.
Changes merged to our monorepo per day, from January to September 2026.
In order to support this growth, we built Scion, an in-house version control system, and fully migrated our monorepo from git in five months. We also built and shipped a code review surface (called Antique), code search, a rich source control IAM system, novel ways of managing and landing large amounts of reviewed code, and more, all in that same time period. In this post, we’ll focus on how we built Scion specifically. It makes for an interesting case study: Claude’s ability to write code was both what put us in this situation in the first place and how we were able to quickly build a high-quality, scalable system to deal with it.
Growing our monorepo
Before we explore what we built, we should acknowledge how unusual our workload is. Unsurprisingly, Anthropic uses Claude to write software far more than almost any other company, so we’re often the first to see where tools built for human scale start to strain. Source control is just one example of this. While we don’t expect many organizations to have these problems in the very near term, we suspect it won’t be too long before others who use AI coding tools experience these same pressure points, which is why we wanted to share what we built and what we learned.
Git is a decentralized system: every clone is a complete, self-contained repository that can compute diffs, read history and blame, and check out any revision while fully offline. For the vast majority of repositories, this is the right design, and it’s a large part of why git became the standard.
As our monorepo grows, it increasingly doesn’t fit that design space. The history of our main branch alone is almost 100 GB, and a compressed working copy is over 25 GB. We perform on the order of 25 million code checkouts per day for CI, before counting developer environments, agent sandboxes, and research jobs. Fetched naively, that would be over 600 PB of git traffic per day.
Git offers tools for working with a slice of a repository, such as shallow clones, sparse checkouts, and promisor remotes. Beyond these, there are standard workarounds for large monorepos, like internal git mirrors and repository snapshots (seeds) kept in blob storage. We’ve used all of them—at our peak, we operated several hundred internal git mirrors to deal with the load. This bought us time, but they became harder to operate as our merge rate increased. Seeds fell further from the tip of main between refreshes, and it took more and more care to keep operations that depend on history, like diff and blame, working on partial clones.
The typical setup for scaling git checkouts.
Taking a step back, we noticed that, like most companies, we were using git as a centralized system with one authoritative copy, but nearly all of our clients were agents and jobs that are online by definition. The properties that make git excellent for distributed, offline work were actively undermining our ability to scale as the repo grew. So we asked ourselves: if we designed source control with the fact that agents are always online in mind from the start, what would it look like?
Principles for agent-scale source control
With agentic coding, many common assumptions about how software is developed are evolving. We embraced these changes when building Scion, which allowed us to take a fundamentally different approach than git on several core principles. Source control for huge monorepos has prior art, notably Google’s Piper and Meta’s Sapling,2 so we were able to build Scion with their hard-won lessons in mind. Our principles are:
Clients are always online. Git assumes that clients work offline and need a complete copy of the repository. Since nearly all of our clients are agents and jobs, we designed Scion’s client and protocols around a server that is always reachable, and have clients fetch data when they need it.
Client-server asymmetry. In git, every client is capable of being a full-fledged server. In Scion, the server answers questions about file history and blame, creates commits, performs merges and rebases, and so on. The client maintains a bounded local object cache, lays out the working copy files on disk, monitors for filesystem changes, and gives users an ergonomic way to work with the server. It can compute very little on its own but, in exchange, it requires much less data locally.
A comprehensive source control service can power many novel applications. With git, a CI job or tool that needs to ask a question about the repository, such as who last changed a line or how two commits are related, has to maintain a local copy of the repo or hope that vendor-specific APIs provide the answer. With Scion, all of the source control queries the client uses are also exposed via API, so in many cases jobs don’t need a local repository at all. Many internal tools, such as our automated bisect and revert pipelines, wouldn’t be practical at scale without this cheap, programmatic access to source control.
Everything must be horizontally scalable. At our peak, we ran several hundred git mirrors, which significantly strained capacity and no longer scaled once the repo outgrew the mirrors’ disks or memory limits. In Scion, the repository’s data is distributed, and every component is independently scalable; there is no fully materialized copy of the repo anywhere, even on the server. There is no equivalent of packfiles (git’s compressed bundles of objects), so no repository maintenance is needed.
Commits must be cheap, incremental, and lock-free. In git, you commit locally and then push to share your work. In Scion, every commit, rebase, or merge happens on the server, so there’s nothing to push, but each of those operations needs to be fast. The cost of creating a commit and updating its downstream data structures has to scale with the size of the change, not the overall size of the repo, or the server can’t keep up. The development lifecycle in Scion discourages refs (pointers to commits, such as branches and tags), except for the main ref or release branches, because global state that every server has to agree on is a looming scaling problem.
The working copy is optional, and sparse by design. Because our monorepo is so large, and because we check out code tens of millions of times a day for CI, we wanted to avoid checkouts whenever we could. With Scion, a CI job that needs the diff between a commit and its merge base, for example, can ask the server for it. The same goes for writes: many write workloads can also skip the checkout and function entirely via API. Scion’s protocol is centered around sparse checkouts, which only contain the directories the client asks for, and virtualized checkouts, which materialize files on demand, so when a job does need files on disk, the client only pays for what it actually reads.
How Scion works
It’s helpful to understand how these principles came together in practice when building Scion. These insights can apply to other source control systems or, more broadly, to other stages of the software development lifecycle.
Data structures
In Scion, the unit of work is a “changeset,” an entry in a write-ahead log. A changeset stores most of what you’d expect from a commit in git. But where a git commit stores a pointer to the tree, a changeset stores a list of the files that changed relative to its first parent,1 along with content-addressed pointers to the compressed file contents in blob storage. Changesets are created server-side and are available everywhere, instantly.
The shape of a changeset in Scion.
This structure lets us accept changesets with very high throughput because there are no packfiles to accept, no locking or cross-server coordination, and no refs to move around. Scion does technically support refs, but since neither creating nor fetching commits involves them, moving one is a compare-and-swap on a single Spanner row that happens separately from creating changesets.
A changeset records only what’s changed, so on its own, it can’t quickly answer questions like who last edited a line or which commits affected a file. To answer those, Scion builds additional data structures from the changesets, including dedicated structures for file blame and path history and skip lists for the commit graph. We call everything that isn’t directly part of the changeset “derived data,” and we compute it all through one generic mechanism. Each type of derived data is defined recursively, so its value for a changeset is computed from its values for that changeset’s parents.
This mechanism has three benefits. First, we can easily add a new type of derived data when a new data structure would make some operation faster. Second, for each type, we can choose whether to compute it eagerly or defer the work, so we avoid materializing data we don’t need. And third, because the client never sees the internals of these data structures, we can optimize them without changing the client. We’ve added new types of derived data many times as the system has grown, such as new indices for performing copy detection or path-based file search.
Scaling Scion
A small fleet of Scion servers provides source control APIs for any operation a client needs, such as getting changesets, computing diffs, finding merge bases, and fetching blobs. All source control data is content-addressed, so a piece of data never changes once it’s stored, and any server can cache it without checking with the others. As a result, the servers are horizontally scalable and require little coordination. They are essentially large caches that can also compute derived data on the fly and write the results back to Spanner.
Scion’s many consumers no longer need to maintain local repositories of their own. Fetching and maintaining the repository used to be a significant maintenance burden for CI jobs or tools that needed to ask source control questions, particularly about commit ancestry and blame. Early in the migration, before we had our own client, repo format, or protocols, Scion only answered these “metadata” queries. Fetching file contents and materializing working copies are far more data-intensive operations, and they needed a design of their own.
Scion’s scn client deviates from git’s fetch protocols in several important ways and, as a result, lends itself to a highly scalable architecture that requires significantly less CPU than git servers. Scion’s negotiation doesn’t tell the server what the client already has; instead, it operates exclusively on trees and blobs the client wants. Starting from a root tree, the client checks its local store for missing trees and requests them recursively, then repeats the process for blobs. Every request is for a specific object that never changes, so any cache can answer it, and the architecture closely resembles traditional tiered caches. The process is also efficient and resumable, because there is no single multi-gigabyte packfile response. Sparse and even virtualized checkouts don’t need special support, because the client simply doesn’t ask for trees it doesn’t want.
In the fleet, the client talks over a socket to a daemon, scion-daemon, that stores objects for the whole node. Most of our nodes need access to the monorepo, and jobs on the same node reuse most of the same objects. Each daemon starts from a periodically refreshed snapshot, then talks only to the tree and blob cache servers in its region, called scion-cache. These cache servers stream objects directly from memory, in the disk format that the daemon will consume, so they don’t need to spend time computing the client’s missing objects or performing delta compression. When a cache is missing an object, it asks the authoritative scion-servers, which read from Spanner or cloud storage as needed.
The scion-daemon, scion-cache, and scion-server all respond to identical RPCs for this protocol, so the client doesn’t need to know the cache topology. Any tier could theoretically talk to any other, but we strictly enforce the tiering to isolate failure domains. We want to avoid a situation where a failure in a regional scion-cache overwhelms the upstream scion-servers and brings down the entire system.
Scion’s checkout architecture.
Each tier of this system maintains a cache hit rate of over 99% and does not require long-lived state, so it’s easy to scale up if needed. Our Scion infrastructure footprint is now 200x smaller than our previous git mirroring infrastructure in terms of CPU and memory requirements. CI and research jobs check out code two orders of magnitude faster (in seconds rather than minutes), which frees up a sizable amount of capacity across the fleet; CI alone realized a 25% CPU capacity win. Neither clients nor caches need to perform repository maintenance, which simplifies the lifecycle management of our jobs.
What we learned building Scion
We started building Scion around the same time as Claude Mythos Preview and Claude Tag became available internally. Both of these releases simultaneously amplified the need for Scion __ and meaningfully accelerated how quickly we could build it.
Here’s a particularly striking example. Earlier in the year, we had largely handwritten the first version of the git-to-Scion ingestion pipeline as a prototype. We thought it was good—until we got our hands on an early internal snapshot of Claude Mythos Preview. We asked it to rewrite the whole thing, and with no further instructions, it produced a version that consumed 20x less memory and was 4x faster, while preserving all of the implicit invariants around ingestion ordering and data structures.
Merged changes to the Scion and Antique codebases per week, from January to September 2026.
What we learned building and operating Scion offers some interesting lessons for what building agent-scale software could look like.
Rapid development with a small team will become more common. A team of seven people built both Scion and Antique (our code review tool, which we could easily write a whole other blog post about), not to mention half a dozen related systems, and fully migrated to them in five months. We did all this while the volume of code merged per day increased by 10x. In the past, developing and deploying a source control system like this would have taken a company years of iterative migration, with many more engineers. We think this sort of fast, nimble migration will become more common in the future.
Engineers are no less valuable, but their work is changing. All of the engineers who worked on this system would now rate Claude as better at writing code than them. But our engineers still supplied the invaluable understanding of the high-level inter-system components and the design-level tradeoffs, making informed choices around the problems we wanted to solve and the scale we knew we needed to achieve. Very often, we found that the role of the engineers was to tell Claude “no.” Agents will sometimes violate core system constraints to satisfy a pattern that should never have been allowed in the first place. This was particularly common in our migration. For example, there were multiple systems that tried to brute force looking up when a change merged to main by linearly reading the commit log instead of asking our code review tool. Anthropic also makes extensive use of adversarial review, and, while this is incredibly effective in many ways, it can also be myopic, so skilled engineers needed to steer Claude away from over-engineering parts of the system in response to hypothetical concerns. For example, one such review was overly defensive about trusting another internal service, which resulted in Claude adding excessive validation and complexity. Our team members still review every change request for the system, but they now examine the intent of the change as opposed to reading every line of code.
We were able to substantially improve optimization and quality. By virtue of Claude’s ability to write immense amounts of code much faster than we could ourselves, Scion is among the most well-tested and well-defended codebases we have ever worked on. Even on our tight timeline, we were able to build hermetic simulations of every non-trivial infrastructure and source control interaction we’ve ever encountered, as well as fuzzing and sophisticated rate limiting. Claude also casually found significant optimizations—for example, an algorithmic optimization to ancestry queries that missed one of our indexes—that would have taken an expert days or weeks of analysis and tuning… and then did it all again the next day.
Observed performance improvements on native Scion repos.
We laid the groundwork for new forms of monorepo security. Managing safety, security, and compliance in a massive monorepo is as important as managing the size and scale. We built Scion with these in mind from the start. It supports rich access control on repositories, as well as the ability to apply permissions to individual directories in order to protect the most sensitive code without losing the benefits of a monorepo. Furthermore, the code review tooling we built can express complex semantic constraints on approvals, which lets us differentiate simple things like comment-only changes from sensitive logical changes, so that human reviewers can focus on the most consequential changes.
A new level of operational excellence is possible. Our team uses Claude Tag heavily, which has helped us monitor each component of the system. For example, we created Slack channels where we tasked Claude with being obsessively focused on the health of a single component. We call these Claudes “superfans.” We have a scion-daemon superfan, a scion-cache superfan, an Antique merge queue superfan, and so on. They have access to our telemetry and logs, and act like an experienced engineer who has nothing better to do than to refresh charts and look for anything strange. We also have traditional alerts for all of our systems, but our superfans can detect subtle and novel issues that make these alerts seem one-dimensional by comparison.
We’re completely rethinking our priors. This project prompted us to take a very hard look at other workflows designed for human scale. A proper merge queue, for example, doesn’t make much sense at agent scale. What does CI even mean when hundreds or even thousands of changes can merge while tests are running? We haven’t been able to effectively replicate the industry standard of a global repository lock on the merge queue, so instead, we’ve invested in post-merge and pre-deploy automated testing. This does mean that concurrent changes can conflict, but Claude can typically fix these conflicts faster than humans can even identify them.
Contributing to the wider ecosystem
We see Scion as just one part of the answer to the scaling concerns that increasingly capable AI agents have raised. We’re sharing these details as an example of how teams can tackle similar challenges, though we don’t expect our solution, or our considerations, to suit every case.
Scion is by no means a suitable replacement for git for general use. The concepts we’ve outlined here really only make sense for truly enormous monorepos, with either tens of thousands of engineers or swarms of agents prolifically writing code. Plus, Anthropic is unique in that our ability to spend tokens for internal use far exceeds what any other business would realistically want to spend. We do this both to address our own software development needs, and to test Claude’s capabilities.
Practically speaking, it’s difficult to offer Scion in a form that would be broadly useful to other organizations. It diverges significantly from git, meaning companies would need to migrate every piece of the development lifecycle, and it requires its own code review, code search, and CI. Our internal versions of these components are highly bespoke, so they would be difficult for other organizations to adopt, and we worry that attempting to build a public version that tries to please everyone wouldn’t actually be very useful.
However, we anticipate that this class of problems will become more commonplace over the next six to 12 months, and it would be an inefficient use of engineering resources for every company using git to face similar challenges alone. Given that, we think the most impactful __ thing we can do is to share our thinking, so that other developers can apply some of the most successful parts of Scion to git without departing from the overall model. A git server doesn’t have to work the same way as a git client does; novel server architectures exist that provide significant scaling improvements. Git platforms can provide comprehensive server-side RPCs like Scion, perhaps even in a standardized way across forges that the git client can learn to talk to. The negotiation protocol doesn’t have to look exactly like it does today, either, and the various sparse and shallow features in git can be made to compose well.
Lastly, we want to acknowledge that the git community has spent nearly two decades scaling the platform for millions of developers. Our contribution is far narrower: sharing our early view into how agentic software development interacts with these systems, so that we can partner with GitHub, GitLab, and the OSS community to support the changing needs of developers. We’re all in it together as the software development lifecycle intersects with the AI exponential.
Acknowledgements
Written by Nick G. and the source control team: S.G., R.K., Dan C., Garrett H., Ben L., Colin M., Joe P. We’re grateful to Vilas J. and Sergiu D. for supporting the source control team on this ambitious journey and Amir O. for early contributions to Antique.
Footnotes
- Storing changed files relative to the first parent of a merge is a stylistic choice; in practice, we’ve found that people only care about history or blame for commits on the main line in trunk-based development in a monorepo.
- Specifically, the server component of Sapling, Mononoke. It pioneered many of the techniques we use in Scion, in particular the Bonsai data model.