2026年10月30日,采用 AT Protocol 构建的联邦式代码托管平台 Tangled 发布 v1.20.0 重大架构升级,彻底告别了过去塞在瑞典单台服务器、靠一个 SQLite 数据库苦撑的 Go 语言单体架构。在 Forgejo 等老牌开源项目仍困在 ActivityPub 协议的跨服同步泥潭时,Tangled 用一套 Rust 纯内存索引加 Git 原生协作对象的组合拳,率先跑通了第一个真正支持跨服务器提交 PR 的联邦化代码平台。

过去二十年,开发者用控制权向 GitHub 换取协作便利;唯一活下来的开放方案是 Git 加邮件列表,代价却是糟糕的交互体验。Tangled 此次重组的野心,是把整个代码平台拆成五个可独立自托管的零件:存代码的 knots、跑 CI 的 spindles、提供界面的 client、收集记录的索引器 Bobbin,以及存放账户与社交数据的个人数据服务器(PDS)。你可以只自托管 Git 存储或 CI 节点,甚至把存储跑在 Cloudflare Workers 上,同时照常和全网开发者无缝协作。

逃离瑞典单机:15 分钟重建的内存索引与五大解耦零件

在此次升级前,Tangled 的前端界面、协议索引和缓存全部捆绑在一个名为 appview 的 Go 单体服务里,跑在瑞典的一台中型服务器上。只要你离瑞典在 50 到 100 毫秒以内,体验尚可,但全球绝大多数开发者都在忍受高延迟。

告别瑞典单机数据库,用纯内存索引实现十五分钟重建
告别瑞典单机数据库,用纯内存索引实现十五分钟重建

重构后的 Tangled 换上了部署在边缘节点的 Svelte 独立前端,并将字体从 Inter 换成了 Timeless Sans;后端则交给了用 Rust 编写的无盘纯内存只读索引器 Bobbin。Bobbin 启动时根本不需要数据库,直接从 hydrant 数据流重建内存状态,并配合 slingshot 处理记录与身份、用 knotmirror 处理仓库代码。这套索引服务宣称已部署在全球 11+ 个区域(注:其代码库目前仅见 knot-bench/src/latency.rs 延迟测试工具,尚未公开这 11 个区域的详细跑分文档)。即便开发者想自己拉起一套替代的 Rust 视图索引,大约 15 分钟就能完成启动与全网数据回填。

Tangled v1.20.0 架构对比:从瑞典单机到五大解耦组件 旧架构:Go 单体服务 (appview) • 瑞典单台服务器 + 单 SQLite 数据库 • 耦合 UI 渲染 (htmx)、索引与缓存 • 仅对距瑞典 50-100ms 内用户友好 • 词典命名空间:sh.tangled.* 新架构:Svelte 前端 + 全球边缘组件 • Bobbin:Rust 纯内存索引,11+ 区域 • Knot2:Rust 单二进制,内置 Git/SSH • 约 15 分钟无盘启动并回填全网数据 • 词典命名空间:org.tangled.*

配合索引层换血,负责托管代码的服务器也升级为用 Rust 重写的 Knot2。它原先在独立的 oyster.cafe/knot2 仓库孵化,现已合入核心单仓,把自定义 Git 服务器与 SSH 服务器打包进同一个二进制文件。此外,平台上线了托管在 Tranquil PDS 上的无密码委托组织账户(默认分配 <name>.tngl.sh 域名句柄),并补齐了原生的 Stacked PRs 工作流——无论是原生 Git 还是 Jujutsu 用户,都能把 PR 作为具有固定 base 和 head commit 的不可变审查轮次来提交并对比版本差异,更新分支只会生成新轮次而不会篡改历史。目前所有自托管节点均需按指南升级至 v1.20.0(支持 NixOS 的 knot-rs 模块或 atcr.io/tangled.org/knot:2 容器镜像)。

把 Issue 塞进 Git 仓库:向项目可移植性妥协的双向验证

去中心化代码平台最难啃的骨头,是项目搬家时 Issue 和 PR 怎么跟着代码走。Tangled 在此次升级中把词典命名空间从 sh.tangled. 整体迁移到了 org.tangled.,并对数据归属做了一次关键的隐性反转。

协作历史随代码仓库整体打包,并由双钥匙双向验证(示意图)
协作历史随代码仓库整体打包,并由双钥匙双向验证(示意图)

早期的 AT Protocol 叙事强调所有数据归个人所有。但在新版模型里,只有个人资料、Star 和关注列表还留在用户自己的 PDS 中;项目的 Issue、PR、评论、表情反应、标签乃至协作者名单,全部被改写成协作对象(COB),直接作为一串 Git 对象链存储在 Knot2 的代码仓库旁边,归属于该仓库的 DID 账户。这意味着,迁移个人身份不再会自动带走你参与过的项目协作历史,但整个代码仓库却获得了完整的项目级可移植性。

个人身份只带走社交关系,代码仓库才带走全部协作历史。

但这立刻引出一个信任漏洞:既然 Issue 和评论现在由别人自托管的 Knot 服务器负责写入,恶意的服务器管理员完全可以篡改数据,把没说过的话塞进你嘴里。

防止自托管节点伪造发言:COB 存储与双向签名验证流 1. 开发者发起操作 在 Web 端提交 Issue 或发表 PR 审查评论 2. 写入仓库 Knot2 生成 Git 协作对象 (COB) 经 Firehose 全局广播 3. 个人 PDS 双向存证 写入 attestation 记录 锁定具体版本防篡改

为了堵住这个漏洞,Tangled 引入了双向验证机制。每当你在某个 Knot 上创建或修改一条记录,Web 端会同时向你自己的个人 PDS 写入一条 org.tangled.graph.attestation 加密证明记录,精确指向该条记录的版本及背后的 COB 变更。Knot2 由此变成了一个专门服务于代码仓库的准 PDS,通过标准 AT Protocol 全局状态流(Firehose)对外同步签名记录,既保住了代码仓连根拔起就能搬家的便利,又守住了个人发言不可伪造的底线。


路线分水岭:为什么 AT Protocol 比 ActivityPub 更快落地?

同样是做“联邦化 GitHub”,此前开源社区的主流押注是基于 ActivityPub 协议的 ForgeFed 路线,代表玩家是 Forgejo(Codeberg 背后的软件)。但直到 2026 年 5 月的月度报告,Forgejo 也才刚刚跑通联邦化的用户关注与动态流,其官方 FAQ 至今仍将联邦功能标记为实验性(experimental),跨实例的审核与访问控制依然悬而未决。

抛弃点对点协商泥潭,用全局状态流与内存筛网实时拼出视图(示意图)
抛弃点对点协商泥潭,用全局状态流与内存筛网实时拼出视图(示意图)

为什么 Forgejo 举步维艰,Tangled 却能率先交卷?核心差异在于底层协议对“状态同步”的处理方式完全不同:

  • 结论.AT Protocol 放弃了实例间点对点协商,用“全局状态流 + 轻量级内存索引”绕开了跨服 PR 的语义对齐泥潭。

在 ActivityPub 的世界里,服务器 A 上的开发者向服务器 B 提一个 PR,需要两台服务器像发邮件一样来回传递消息并对齐状态,一旦涉及代码冲突、权限变更或评论撤回,跨服状态机极易崩溃。而 Tangled 借助 AT Protocol,把身份(DID)、存储(Knot/PDS)和视图(Bobbin)彻底拆开——所有变更直接变成带签名的记录扔进全局 Firehose,由 Bobbin 这样的只读内存索引在边缘端实时拼出全局视图。因为架构天生解耦且对 AI 极其友好,像 Mitchell Hashimoto 这样的一线极客已经直接动手写出自定义的 CI 节点(mitchellh.com/tack),甚至有人把自定义 Knot 跑在了 Cloudflare Artifacts 上。

但极客与开源维护者在决定是否迁移时,仍需看清这套架构尚未消解的两道现实边界:

  • 风险.CI 状态无法随协议自动迁移,且“拥有数据所有权”并不等于拥有独立的开发者社交网络。

第一道边界在工具链内部。虽然代码和 Issue 都能跟着 Git 仓库走,但负责持续集成的 Spindle 组件依然把流水线配置、运行状态、日志、密钥和 Webhook 存在自己的本地数据库里,这些都不属于可自动迁移的 AT Protocol 记录。至于私有仓库、命令行工具(CLI)和多语言 SDK,也还要等接下来几周的分批发布。

第二道边界则在社区生态。正如 Hacker News 与 Lobsters 社区多位开发者所指出的,哪怕你辛辛苦苦自托管了 PDS 和 Knot2,只要全网开发者依然习惯打开 tangled.org 这个官方主站去搜索项目、浏览代码,项目的实际可见度与协作入口就依然攥在官方手里。Tangled 确实给开源世界造出了一把随时能掀桌子的救生艇,但接下来真正的看点,是社区里会不会有人真正跑起独立的第三方 Bobbin 索引和自定义前端,去分流官方入口的注意力引力。