Motrix 2.0.0-beta.4 发布说明全解:一次"未发布"的 v2 预发布尝试与隔离签名流水线恢复修复
Motrix 2.0.0-beta.4 是一次并未对外发布的预发布尝试:5 个桌面构建 job 全部成功,但隔离的 Windows 最终处理在 fail-closed 校验阶段终止、macOS 签名环境未获审批、Snap amd64 中途取消,最终没有任何 GitHub Release、容器镜像或 Snap Store revision 产生。本文以仓库 docs/release-notes/2.0.0-beta.4.zh-CN.md 为主体,结合 .gitattributes、scripts/release-signing-input.mjs、docs/docker-server.zh-CN.md 等源码与配置,还原这次发布尝试的技术背景、v2 原计划功能范围、恢复修复细节与产物清单,并说明如何在发布说明的历史语境中正确理解该版本。
发布背景:为什么需要保留一份"零分发"的历史记录
beta.4 所在的 Motrix v2 系列是一次整体重构:桌面应用与全新的 Headless Server 共用下载内核,并引入 MDXP 任务交接与沙箱化插件系统。这份发布说明的开头用醒目的 [!IMPORTANT] 块交代了本次尝试的结局——发布未完成、外部分发为零,文档中所有描述均为"原计划范围"的历史记录,而非可用的下载产物。
文档同时给出明确的替代指引:实际使用请改用 2.0.0-beta.5 发布说明(及其后续版本)。同一段落在 beta.5 的说明中亦有呼应——beta.4 说明"保留了前序失败记录"。因此阅读本文及原始文档时,应把 beta.4 视为发布流水线的故障档案与版本演进里程碑,而非可安装的软件版本。
本次发布尝试的执行结果:一次逐步 fail-closed 的流水线
从源码与发布说明可以拼出这次发布尝试的完整轨迹:
- 5 个桌面构建 job 全部成功:macOS
arm64/x64、Windowsx64、Linuxarm64/x64。Windows 的 LF 固定修复使全部 10 个固定摘要的签名控制文本在 Windows checkout 后保持 canonical LF,固定 SHA-256 校验通过。 - Windows 隔离 finalize 在读取任何 Authenticode secret 前 fail closed。失败根因是清单排序约定不一致:真实签名 manifest 包含 2,434 个无重复条目,按目录优先的 DFS 顺序排列;而 verifier 要求每个 canonical 相对路径按全路径字典序排列。首个逆序出现在
js-yaml/lib/schema/…目录下的条目排在同级文件js-yaml/lib/schema.js之前,触发了校验失败。 - macOS 签名环境未获审批,两个 macOS finalize job 被取消;Snap
amd64在 strict build 期间取消(arm64已成功构建并上传)。 - 由于 finalize 阶段整体失败,assemble、GitHub Release、R2 更新数据源发布、container publish、Store upload 与
latest/edgerelease 均未执行——这也解释了为何产物矩阵中的镜像地址需要与"并未发布"的声明并列阅读。
这一"先构建、后隔离校验、任一环节失败即整体停止"的顺序,正是仓库在隔离签名管线中反复强调的 fail-closed 设计(详见下文对 verifier 源码的解读)。
已包含的发布恢复修复:把字节确定性带进隔离签名管线
发布说明列出的四类恢复修复,全部指向同一个目标:让发布产物可复现、可验证、可被审计。
text eol=lf:Windows checkout 的字节稳定性
在
.gitattributes中把全部 10 个固定摘要的隔离签名控制文本路径声明为text eol=lf,使 Windows checkout 保留 canonical LF 字节,同时不放宽原始字节 SHA-256 校验。
仓库根目录 .gitattributes 正是文档描述的实现。文件开头注释解释了设计动机:这些文件"byte-for-byte hash-pinned"(逐字节固定摘要),需要让 Windows 上的 checkout(默认 autocrlf)与提交的 blob 保持字节一致。第 9–18 行恰好列全了这 10 个控制文本:
electron-builder.signing.jsonbuild/entitlements.mac.plistbuild/installer.nshscripts/release-signing-tool/package.json与package-lock.jsonscripts/electron-package-size-budgets.jsonscripts/electron-package-utils.mjsscripts/before-build-use-staged-dependencies.mjsscripts/native-binary-target.mjsscripts/release-signing-input.mjsscripts/verify-electron-package.mjs
与之配套,同一文件第 5 行把 THIRD_PARTY_LICENSES/** 声明为 -text,即彻底禁用换行转换,保证第三方许可文本在三种平台 checkout 后与提交 blob 逐字节相同。两者共同构成"签名/许可输入在跨平台传递中不被隐式改写"的防线,而摘要校验仍然严格——eol=lf 只是固定了 checkout 表示,并未放宽对原始字节 SHA-256 的验证。
隔离交接前的 commit 信息保留与依赖补全
- 保留完整触发 commit 信息:在进入隔离最终处理前,为 Windows signing-input 交接保留触发 commit 的完整信息。这一点在 scripts/release-signing-input.mjs 的 manifest 结构中得到印证——verifier 会校验
manifest.commit必须与 job 传入的options.commit完全一致(第 772–784 行),任何不匹配都会导致校验抛错并中止。没有完整的 commit 信息,就无法建立"产物来源于哪个源码版本"的可追溯链条。 - 补全 Electron runtime 依赖:确保打包后的桌面应用包含启动时所需的 module。仓库维护了一份显式的运行时依赖清单 scripts/electron-runtime-dependencies.json,其中
common段列出了所有受支持目标共用的打包期模块(如@motrix/mdxp、better-sqlite3、electron-updater、quickjs-emscripten、ws、undici、zod等),并按平台细分required/optional依赖(例如 darwin 的@resvg/resvg-wasm为必需、electron-liquid-glass为可选)。这类"显式声明 + 打包校验"的组合(对应脚本scripts/verify-electron-package.mjs)正是用来防止运行时才发现缺 module 的手段。 - 暂存已确定的 Snap 产物:在发布到 Store 前,先暂存经过验证且确定的
amd64与arm64两份 Snap 产物,避免发布环节对构建产物的竞态依赖。
verifier 源码中的 fail-closed 校验链
scripts/release-signing-input.mjs 提供了上述修复的可执行实现,值得细读其 verifySigningInput(第 754–824 行)暴露的验证链:
- manifest 元数据强校验:
schemaVersion、commit、target.platform/arch/key、tools.electron/tools.electronBuilder版本、limits均须与 job 逐项相等,否则抛signing input manifest metadata does not match the job(第 772–785 行)。 - 清单排序与唯一性校验:verifier 要求
manifest.files中每个 entry 的path排序后与去重后完全一致,否则抛signing input file inventory must be sorted and unique(第 792–799 行)——这正是 beta.4 中"2,434 条目、目录优先 DFS 顺序"与"全路径字典序"不一致而 fail 的规则所在;到了 beta.5,creator 改用完整路径 code-unit 排序修复了同级文件与子目录条目的先后次序(对比 2.0.0-beta.5 发布说明 的对应修复条目)。 - 实际目录与 manifest 逐字节比对:重新对目录做 inventory,与 manifest 记录比对(第 811–819 行),杜绝"清单与实际不符"。
- 受信输入摘要校验:
verifyTrustedInputDigests(第 560 行起)按TRUSTED_INPUT_SHA256常量表逐一比对受信控制文件(文件头第 36–73 行列出了electron-builder.signing.json、各类.icns/.ico/.bmp资源、installer.nsh等的固定 SHA-256);assertSafeTree(第 302 行起)则对目录树做路径安全断言。
任何一步不通过都会抛出异常,主入口将其打印后置 process.exitCode = 1(第 833–835 行)——这就是"fail closed"的落地形态:在读取任何 Authenticode secret 之前,任何与预期不符的输入都会让流水线整体终止。
v2 原计划的主要变化:重构全景
发布说明的"主要变化"一节勾勒了 v2 的整体蓝图,其中每一条都能在当前仓库结构中找到对应实现(需要说明:beta.4 记录的是当时规划,仓库代码随后续 beta 持续演进)。
桌面应用从头重建
使用 Electron 43、React 19 和 TypeScript 7 从头重建桌面应用,提供可自定义 Dashboard、深色模式、跨平台应用菜单,以及更清晰的任务检查器反馈。
注意这里的版本号是 beta.4 时代的快照。当前仓库根目录 package.json 中 devDependencies 已演进为 Electron 44.1.1(第 108 行)、React ^19.2.8(第 154 行)、TypeScript ~7.0.2(第 115 行)——与 scripts/release-signing-input.mjs 中冻结的 ELECTRON_BUILDER_VERSION/ELECTRON_VERSION(26.15.7/44.1.1)一致。UI 部分对应 src/renderer/(components、routes、hooks、layouts 等),跨平台应用菜单与任务检查器在 src/main/menu 与 src/core/inspector-activity 等模块实现。
共用与宿主无关的下载内核
桌面应用和全新的 Node/Web Server 共用与宿主无关的下载内核,支持 SQLite session 恢复、Tracker 管理、UPnP/NAT-PMP,以及 HTTP、FTP、BitTorrent 和磁力链接下载。
仓库把与 UI 无关的核心逻辑集中放在 src/core 下,可见其模块划分与文档一一对应:
- SQLite session 恢复:
src/core/session/(如session-manager.ts、motrix-database.ts、migrations/)负责会话与数据库;Engine 侧目录src/core/engine/提供监督与任务选项。 - Tracker 管理:
src/core/tracker/(共 11 个文件)。 - UPnP/NAT-PMP:
src/core/nat/settings-nat-provider.ts与src/main/nat/。 - 多协议下载:
src/core/task/、src/core/torrent/,BT/磁力解析在src/core/torrent/下。
"与宿主无关"体现在共享模块可同时被桌面主进程与 Server 端复用——桌面进程入口 src/main/index.ts 与 Server 入口 src/server/index.ts 分别装配,但底层能力统一收敛于 src/core。
MDXP 任务交接与 device-code 配对
官方 CLI 和浏览器任务交接统一使用 MDXP,并支持本地安全发现及远程 Server 的 device-code 配对。
MDXP(Motrix 的跨端交接协议)贯穿 src/core/bridge、src/main/bridge 与 src/server/bridge,配套 src/core/bridge/mbp1/ 协议实现、web-socket-bridge-server.ts 与证书固定的 *.pem 文件。CLI 与浏览器扩展交接、device-code 配对、配对提示与撤销流程在 e2e/bridge 下有可直接阅读的 Playwright 用例(如 pair-and-submit.spec.ts、remote-extension-wss.spec.ts)。
QuickJS 插件沙箱与签名插件
提供带能力授权的 QuickJS 插件沙箱、已签名的内置插件和应用内插件市场。
QuickJS 沙箱对应 src/core/plugin/ 下能力模块的 src/core/plugin/capabilities/、host/、runtime/、permissions/、grants/,运行时依赖 quickjs-emscripten(已列入 scripts/electron-runtime-dependencies.json 的 common 依赖)。签名机制可参考 scripts/builtins-signing.pub.pem 与 src/shared/builtin-signing.ts,插件市场相关命令位于 src/main/plugin/ 与 src/server/plugin/。
面向 NAS 的持久化 Server 容器
面向 NAS 和家庭服务器提供持久化、多架构 Server 容器,原计划同时发布到 Docker Hub 与 GHCR。
容器镜像的发布形态在仓库 docs/docker-server.zh-CN.md 中有详细说明:正式带 tag 发布会把同一镜像发布到两个 registry——docker.io/motrixapp/motrix-server 与 ghcr.io/agalwood/motrix-server;compose.yaml 通过 MOTRIX_IMAGE 环境变量(默认 motrixapp/motrix-server:latest)选择镜像源,并内置非 root 用户、只读根文件系统、no-new-privileges、数据/下载卷与 MDXP 端口等部署参数。beta.4 阶段并未真正发布这两个地址的镜像,这一点以发布说明原文为准。
重建发布流水线
隔离 macOS 签名步骤,并明确支持未签名的 Windows 最终处理,同时加入安装包验证、第三方声明和 SPDX SBOM。
对应脚本散落在仓库 scripts 目录:before-pack-verify.mjs、verify-electron-package.mjs、generate-third-party-notices.mjs(配套 scripts/third-party-notices.config.json 与生成的 THIRD_PARTY_NOTICES.zh-CN.md)、verify-snap-artifact.mjs、verify-appimage-artifact.mjs、verify-container-publication.mjs 等。spdx/SBOM 相关配置见 electron-builder.json 与 Dockerfile 上下文。
预发布测试须知与测试项
发布说明明确把本版本定性为预发布软件,并列出了两条对用户至关重要的安全边界:
- 安装前备份现有 Motrix 应用数据与下载文件;v2 尚处于"从头重建"阶段,Motrix v1 数据的迁移路径未经验证,禁止让 beta 使用唯一一份 v1 数据。
- 并行测试:条件允许时,通过独立的系统账户、设备或 Docker 数据目录与现有环境并行测试 v2,不要让 beta 成为重要下载文件的唯一存储位置。这条建议在 Docker 部署语境下对应 docs/docker-server.zh-CN.md 中关于数据目录与
MOTRIX_DATA_DIR的隔离说明。
原计划的测试项聚焦三块:
- 下载协议覆盖:HTTP、FTP、BitTorrent 与磁力链接下载,包括暂停/继续与 session 恢复。
- 交接与插件:桌面集成、通过 MDXP 的浏览器和 CLI 任务交接、沙箱化插件。
- Server 形态:Headless Server 部署、数据持久化与远程配对。
这些测试项与当前仓库 e2e、tests 下覆盖下载生命周期、会话恢复、bridge 配对的用例类型高度对应,可作为验证 v2 稳定性的检索起点。
原计划下载与容器产物矩阵(均未实际发布)
下表完整继承自发布说明,标示了当时规划的分发矩阵。文档特别注明这些产物 并未发布,仅供理解 v2 的分发规划:
| 发布方式 | 架构 | 原计划产物 |
|---|---|---|
| macOS 12 或更高版本 | arm64(Apple Silicon)、x64(Intel) |
DMG 和 ZIP |
| Windows | x64 |
NSIS 安装包(.exe)和 ZIP |
| Linux | x64、arm64 |
DEB 和 RPM |
| Docker Hub / GHCR | linux/amd64、linux/arm64 |
两个 registry 中均发布不可变 tag 2.0.0-beta.4 |
| Snap Store | amd64、arm64 |
latest/edge |
容器地址(原计划):docker.io/motrixapp/motrix-server:2.0.0-beta.4 与 ghcr.io/agalwood/motrix-server:2.0.0-beta.4。若在镜像源中检索这些 tag 返回 404 或 manifest unknown,属于预期结果——正如 docs/docker-server.zh-CN.md 所述,首个实际发布容器镜像的版本出现前不应期待镜像存在,也不要改拉取未经校验的替代镜像。需要理解镜像 tag 语义与数据持久化/网络/升级方法时,可查阅该部署指南。
已知发布限制
发布说明在"已知发布限制"中明确列出了 beta.4 的范围边界,这些内容不应被误读为遗漏:
- 未发布 AppImage;Flatpak 已单独验证,但未随该版本 tag 发布。
- 不提供 Windows
arm64与任何 32 位安装包。 - 原计划的 Windows 安装包不会进行 Authenticode 签名,可能触发 Windows SmartScreen 警告——由于本次发布整体未完成,实际并未产出 Windows 安装包。
- 原计划的 beta container tag 是不可变的,不会更新
latest、stable或其他稳定版浮动 tag。这与当前 docs/docker-server.zh-CN.md 中"预发布版本不更新 floating tag、只有两个 registry 的不可变 manifest digest 一致后才推进浮动 tag"的现行规则一脉相承。
从 beta.4 到 beta.5:发布问题的接力修复
理解 beta.4 的最佳方式是与 2.0.0-beta.5 发布说明 对照阅读:beta.5 明确记录了"排序不一致"修复的完整方案——在序列化前以完整相对路径为 key,把每份 Windows signing-input manifest 按 canonical code-unit 顺序排序,creator 在 inventory 收集完成后做一次全局排序,verifier 使用同一 comparator。这会让同级文件 js-yaml/lib/schema.js 排在 js-yaml/lib/schema/… 目录条目之前,取代目录优先的 DFS 顺序,同时保持路径唯一性、路径安全、固定摘要验证与 fail-closed 隔离不变。
由此可以清晰看到这一版发布恢复修复的演进脉络:beta.4 定位并暴露了 manifest 排序语义的分歧,beta.5 给出了 creator 与 verifier 统一排序规则的修复。这也是系列发布说明作为"发布流水线工程档案"的独特价值——它记录了真实发布系统中字节级可复现性(eol=lf)、可审计交接(commit 溯源)、fail-closed 验证(摘要与清单强校验)等生产级工程实践。
反馈与后续追踪
按发布说明的建议,遇到可复现问题时应向仓库提交 Issue,并附上操作系统、架构、安装包类型与复现步骤——这些信息对定位隔离流水线问题尤为关键(beta.4 的排序失败正是因为真实 manifest 与 verifier 预期不一致才暴露)。进一步追溯该版本技术细节时,可在仓库中顺藤摸瓜阅读以下文件:
- .gitattributes:10 个签名控制文本的
text eol=lf声明与THIRD_PARTY_LICENSES/** -text规则。 - scripts/release-signing-input.mjs:signing-input 的 create/verify 双模式与 fail-closed 校验链。
- scripts/electron-runtime-dependencies.json:打包期 Electron runtime 依赖清单。
- docs/docker-server.zh-CN.md:Server 容器的镜像、tag、安全与持久化说明。
- docs/release-notes/2.0.0-beta.5.zh-CN.md:manifest 全路径字典序排序修复的完整记录。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00