Skip to content

Latest commit

 

History

History
44 lines (24 loc) · 7.07 KB

File metadata and controls

44 lines (24 loc) · 7.07 KB

Agent Note: 仓库内 Landlock 发布

Status: implemented

English | 中文

问题

@deepseek-ai/node-addon-landlock-run 源码已经与其 DeepSeek Harness 消费方一同位于 native/landlock-run 下,但此前仍保留独立的 pnpm workspace 和锁文件,并依赖一个独立仓库发布到 npm。Harness 包使用 npm 注册表中的固定版本,因此同一个 PR(Pull Request)可以同时修改启动器约定及其消费方,却无法一起测试这些改动。源码仓库的原生工作流可以演练打包流程,但不会发布它实际测试过的产物。

发布镜像还造成重复的发布协调工作:导出源码、更新另一份锁文件、运行另一套发布工作流、发布原生包家族,然后回到本仓库更新注册表依赖。npm 用户的实际需求并未改变,这种拆分却让每个二进制更难对应到其源提交,也让发布回滚和安全修复协调更困难。

现有的非 scoped npm 包名归独立发布账号所有,而不属于 @deepseek-ai 组织。因此,仅迁移工作流仍会让发布依赖仓库发布归属之外的个人凭证。

此次整合必须保留平台选择机制。公开分发有意采用一个 JavaScript 入口包,并为 Linux x64 和 arm64 分别提供二进制包;合并仓库归属并不意味着要把所有二进制文件放进同一个 tarball,也不意味着要按照启动器版本发布所有 DeepSeek Harness 包。

决策

native/landlock-runnative/landlock-run/packages/* 属于仓库根 pnpm workspace,并使用根 pnpm-lock.yaml。Harness 消费方将 @deepseek-ai/node-addon-landlock-run 声明为 workspace:*,因此开发、类型检查、构建和 PR 测试都会从同一个 checkout 解析入口包。根 TypeScript 项目图会先构建该入口包,再构建消费方;仓库清理器负责清理其直接生成的 lib/ 输出目录。

公开 npm 分发边界由 3 个归组织所有的包组成,它们共用一个启动器包家族版本:@deepseek-ai/node-addon-landlock-run@deepseek-ai/node-addon-landlock-run-linux-x64@deepseek-ai/node-addon-landlock-run-linux-arm64。入口包继续通过 optionalDependencies 声明两个平台包;它们在 manifest(元数据清单)中的 oscpu 字段让 npm 只安装兼容的包。仓库约束要求这 3 个包名设置 publishConfig.access: public,并要求其版本与私有启动器 workspace 根包一致。原先的非 scoped 包名不属于本仓库的发布目标。这 3 个已不再是唯一的公开包:按序列区分 access 的决策让 vendored 框架九包也公开发布,而 dsh 族保持受限。

主仓库同时负责原生 CI 和发布。Landlock Run 会为相关 PR 和 master 推送运行,并在各自匹配的原生 runner 上构建每个平台包。手动触发的 Landlock Run Release 工作流会构建两个平台的二进制文件,将其作为工作流产物传递,组装并验证完整的包家族,打包出内容不可变的 npm tarball,安装并实际运行这些 tarball,之后才允许受保护的发布作业执行。发布顺序是平台 tarball 在前,最后发布将它们列为可选依赖的入口 tarball。发布使用 landlock-run-vX.Y.Z tag,避免启动器版本与 monorepo 中其他发布家族发生冲突;预发布版本使用 npm 的 next dist-tag。

沙箱打包安装演练不再允许 npm 注册表提供启动器。它会将当前 checkout 的入口包、匹配的原生包和 harness 依赖闭包一起打包,把这些本地 tarball 安装到仓库外部的纯 Node 消费方中,并在测试约束效果或失败闭合行为之前,证明所安装的启动器可执行、与原生构建产物字节完全一致,且具有正确的 ELF 架构。

曾考虑的替代方案

  • 保留独立仓库作为发布镜像:不予采纳,因为在权威源码已经迁入本仓库后,这仍会保留拆分的锁文件、源码导出、测试使用陈旧注册表版本的时间窗,以及跨仓库发布序列。
  • 发布一个包含所有平台二进制文件的 npm 包:不予采纳,因为用户会下载无法在其主机上运行的二进制文件,而且 npm 无法再利用包级 oscpu 筛选。仓库归属与 npm 包布局是两个彼此独立的选择。
  • 让启动器使用 DeepSeek Harness 根版本,并递归发布整个 monorepo:不予采纳,因为本次改动负责的是一个由 3 个包组成的公开包家族,而不是独立的 @deepseek-ai/dsh-* 基线。产物优先的 npm 基线提案明确将原生 workspace 排除在其目标集合之外。
  • 在一个发布作业中交叉编译两个二进制文件:不予采纳,因为仓库内已提交的包矩阵已经为每种架构分配了原生 GitHub runner,无需再把交叉工具链纳入信任边界。

后果

同一个 PR 可以同时修改启动器协议、TypeScript 入口代码、原生源码、harness 消费方式和发布路径测试,并从同一份锁文件解析这些内容。发布 tag 现在标识源码、消费方集成、构建指令,以及主仓库测试过的 tarball。独立镜像已不再属于发布路径,可以在第一次成功从本仓库发布后归档。

npm 消费方改为安装 @deepseek-ai/node-addon-landlock-run;原先的非 scoped 包名不会被静默重定向。受支持的 Linux 主机会下载 scoped 入口包及与其架构匹配的包,并跳过另一架构的包。不受支持的主机不会收到平台二进制文件,并继续沿用现有的确定性失败闭合探测路径。

实现涉及的文件比只修改一行依赖更多,因为仓库还必须负责 workspace 约束、TypeScript 构建顺序、清理、CI 触发条件、发布 tag、锁文件生成、将已安装二进制与 workspace 构建进行比较、发布文档和生成的第三方声明。行为边界仍然很窄:此次改动只影响 Landlock 包家族及其 3 个直接 workspace 消费方,不改变其他 DeepSeek Harness 包的版本或发布状态。

第一次发布 scoped 包时,必须通过 npm-publish 环境的 NPM_TOKEN 使用 @deepseek-ai 组织 token,因为 npm 只有在包已经存在后才能配置 trusted publishing。完成 bootstrap 后,必须让 3 个包都授权本仓库的发布工作流,才能移除后备 token。npm 仍会按顺序发布各个包,且不提供跨包事务,因此发布失败可能留下只完成了一部分的版本。由于 npm 会拒绝已经发布的同名同版本包,操作人员必须检查注册表并只发布缺失的 tarball,而不能原样重新运行工作流。Linux x64 和 arm64 runner 仍提供权威的二进制构建与真实内核检查;macOS checkout 可以验证入口包和不受支持平台上的行为,但不能取代这些作业。

本说明仅取代沙箱 Agent Note中有关发布镜像和开发源码时依赖注册表固定版本的表述;该 Agent Note 仍负责沙箱行为、runner 选择和强制执行语义。