deepseek-harness 的 landlock-run 支持矩阵解析:平台包、内核 ABI 与 fail-closed 降级策略
【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness
本指南以 native/landlock-run/docs/support-matrix.md 为骨架,结合 native/landlock-run/docs/architecture.md、native/landlock-run/docs/cli-contract.md、native/landlock-run/docs/packaging.md 以及入口包源码与发布脚本,系统讲解landlock-run这一 Landlock 自约束启动器(launcher)的平台支持矩阵:哪些平台提供预编译二进制、内核 ABI 如何决定full/partial/unusable三态探测结论、为什么 darwin/win32 及其他 Linux 架构被刻意排除,以及不支持平台上的 fail-closed 行为如何在工程上落地。读完本文,你将理解该包族“平台包 + 入口包”的发布模型与支持边界的判定逻辑,并能在自己的消费侧正确解读探测结果、规划新增平台。
一、支持矩阵概览:两个平台包,一个通用二进制
landlock-run采用与 esbuild 等原生包一致的“入口包 + 平台包”分发模型(详见 native/landlock-run/docs/packaging.md)。目前官方发布、作为“builder of record(权威构建者)”支持且验证过的平台只有两个:
| 平台包 | GitHub Runner(权威构建者) | 说明 |
|---|---|---|
@deepseek-ai/node-addon-landlock-run-linux-x64 | ubuntu-24.04 | 静态链接 musl —— glibc 与 musl 发行版通用 |
@deepseek-ai/node-addon-landlock-run-linux-arm64 | ubuntu-24.04-arm | 静态链接 musl —— glibc 与 musl 发行版通用 |
两个关键设计含义:
- 静态 musl 二进制,跨 libc 通用:二进制由
scripts/build.ts用发行版musl-gcc原生编译、静态链接(不依赖 loader 或 libc),因此一个二进制同时覆盖 glibc 与 musl 发行版。这也解释了为什么平台包package.json中刻意不声明libc字段——详见 native/landlock-run/packages/linux-x64/package.json(os: ["linux"]、cpu: ["x64"])。 - “权威构建者”是支持的前提:每个平台包都对应一个原生 GitHub Runner,在该 runner 上构建并经过完整验证流程后才发布。这是“no-cross-toolchain(禁止交叉工具链)”规则的直接体现——新增平台必须同时新增一个能构建并证明它的原生 runner。
每个平台包的prebuilds.json声明包内允许存在的二进制,例如 native/landlock-run/packages/linux-x64/prebuilds.json:
{ "platform": "linux-x64", "binaries": [ { "tool": "landlock-run", "kind": "static-musl", "path": "bin/landlock-run" } ] }该清单是检入仓库的元数据,native/landlock-run/scripts/github-matrix.mjs 从中派生出 CI 与 Release 矩阵(RUNNERS映射:linux-x64 → ubuntu-24.04、linux-arm64 → ubuntu-24.04-arm)。也就是说,新增一个平台只需新增packages/<platform>/包并在矩阵脚本与支持矩阵文档中各加一行,自动化无需改动 workflow。
二、内核要求:Landlock 5.13+,但“探测”才是唯一权威
支持矩阵强调了一个容易误读的边界:平台包存在 ≠ 一定能强制执行。运行强制(enforcement)还需要宿主内核满足:
- 内核启用并强制 Landlock(Linux5.13+引入);
- 内核在编译时构建了 Landlock,且对应的 LSM 未被禁用。
关键结论来自探测(probe)而非版本号:“探测——而不是内核版本——才是权威”。一个编译时未包含 Landlock、或 LSM 被禁用的内核,无论版本多新,探测结果都是unusable。这正是指南中“The probe — not the kernel version — is the authority”的含义。
三态判定:full / partial / unusable
协商得到的 Landlock ABI 级别直接决定探测结论:
| 探测结论 | 判定条件 | 行为含义 |
|---|---|---|
full | 本构建已知的每一个访问类型都被当前内核 ABI 覆盖 | 完整强制 |
partial | 旧 ABI 只能覆盖访问类型的一个子集 | 仍然对它支持的一切保持受限 |
unusable | Landlock 缺失或被禁用(含平台包缺失) | 启动器拒绝运行任何命令 |
从源码看,判定逻辑在 native/landlock-run/packages/entry/src/main.c 中实现:
MAX_ABI = 5(main.c 第 94 行),landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)协商内核 ABI(第 231 行);abi < 0(ENOSYS/EOPNOTSUPP)即不可强制执行,fail(NOT_ENFORCED_MESSAGE, NULL)直接失败关闭。*partial = abi < MAX_ABI(第 237 行),随后fs_mask_for_abi()按 ABI 级别裁剪受控访问位集(第 185-191 行:ABI 1 为 0..12 位,ABI 2 加REFER,ABI 3 加TRUNCATE,ABI 5 加IOCTL_DEV)。- 探测模式下用最大规则集真实限制一个短命子进程并输出一行结论:
landlock: fully enforced或landlock: partially enforced (older ABI)(第 281 行)。
之所以采用功能性探测而非--version式版本检查,是因为存在“内核有 syscall 却拒绝强制”的情况——只有真的把自己限制住,才是诚实信号(main.c 第 270-275 行注释)。JS 侧 native/landlock-run/packages/entry/src/index.ts 的probe()将探测进程输出映射为'full' | 'partial' | 'unusable'三态。
partial 的实际表现
旧 ABI 下,超出版本支持范围的访问类型(如 ABI 3 之前的truncate)不受管控,但内核支持的一切仍然受限。landlock-run在受限运行前打印一行 stderr:landlock-run: partial enforcement (older Landlock ABI)(main.c 第 288-293 行),然后照常继续执行命令。消费方(agent harness / sandbox 能力)需要在自己的“模式词表(mode vocabulary)”中为每一级做出承诺——这正是支持矩阵中“still confined for everything it supports”的工程落点。
三、刻意不支持(Deliberately unsupported)
支持矩阵明确列出三类刻意不支持的平台,并各自给出理由:
- darwin(macOS):macOS 消费者通常通过系统自带的
sandbox-exec/Seatbelt 做限制,没有需要分发的二进制。这类“兄弟启动器”属于其他仓库,不是本仓库的移植对象。 - win32(Windows):Windows 的限制启动器会是另一种机制、放在自己的仓库里,而不是本仓库的移植。
- 其他 Linux 架构(riscv64、s390x 等):还没有原生 CI 权威构建者。
no-cross-toolchain规则决定了:平台包只能与一个能构建并证明它的原生 runner 一起加入,不允许用交叉编译“补”出一个无人验证的二进制。
从仓库结构看,packages/目录下只有entry/、linux-arm64/、linux-x64/三个子包,与矩阵完全一致;入口包 native/landlock-run/packages/entry/package.json 的optionalDependencies也只列这两个平台包。不支持的平台刻意不出现在 optionalDependencies 中——这是“不支持平台不发布平台包”的元数据落地。
新增平台的完整路径
依据 native/landlock-run/docs/architecture.md 的 “Adding a platform” 一节,新增平台需要同时完成:
- 新增
packages/<platform>/包(含带os/cpu的package.json、prebuilds.json、README、LICENSE); - 在 native/landlock-run/scripts/github-matrix.mjs 的
RUNNERS中登记对应的原生 GitHub Runner; - 在本支持矩阵文档中补充一行;
- 同步更新包元数据、
prebuilds.json、lockfile 以及支持/发布文档(同一变更内完成)。
四、不支持平台上的 fail-closed 行为:一条降级路径,而不是两条
支持矩阵的最后一句点明了消费侧的关键保证:
不支持平台上的消费者会解析到一个不存在的启动器路径,探测结果为
unusable,然后失败关闭(falls closed)——这就是文档化的降级行为,由 CI 的 darwin 分支实际演练验证。
这条行为链在 native/landlock-run/packages/entry/src/index.ts 中实现:
launcherPath()拼接@deepseek-ai/node-addon-landlock-run-${process.platform}-${process.arch}并尝试require.resolve;- 解析失败(平台无包、或 optionalDependency 未安装)时,返回一个位于入口包自身
node_modules内的确定性但永不存在的回退路径; - 存在性被刻意不检查:无论二进制是否缺失,统一交由
probe()作为唯一可用性信号——缺失二进制与不强制执行的内核同样探测为unusable。
这样设计的目的在源码注释中写得很清楚:消费者只有一条降级路径,而不是两条(“Consumers get one degradation path, not two”)。无论失败原因是“这个平台没有包”还是“内核不支持 Landlock”,消费方的答案都是同一个:不要信任这个启动器。这保证了失败语义简单、可测试、可文档化。
此外还有两个配套保证:
- 无环境变量输入:启动器与入口包都不读取环境变量,“由哪个二进制限制进程”永远不可能被环境决定(architecture.md 与 index.ts 头注释均有强调);
- CI 演练:darwin 这一“刻意不支持”平台正是 CI 中验证 fail-closed 降级路径的常设测试场景,确保不支持平台的消费者行为不会意外漂移。
五、支持边界的工程化收尾:从矩阵到发布验证
支持矩阵不是孤立的文档,它与整个构建/发布流水线互相咬合:
- 矩阵单一来源:
prebuilds.json+os/cpu字段是检入的包矩阵元数据;native/landlock-run/scripts/github-matrix.mjs 从它派生 CI 与 Release 矩阵。node scripts/github-matrix.mjs ci每个平台生成一条 CI leg,release-prebuild每个平台包生成一条发布 leg。 - 二进制与入口包同版本:CLI 解析器与二进制在同一包族中共同版本化,杜绝“解析器落后于二进制”的漂移(architecture.md);三个公开包共享同一版本号,发布时校验 tag 与所有包版本一致(native/landlock-run/docs/release.md)。
- 发布前门禁:
- 平台包
prepack跑 native/landlock-run/scripts/verify-launcher-binary.mjs:声明的二进制全部存在、可执行、ELFe_machine与声明的cpu匹配、bin/中没有未声明文件; - 入口包
prepack跑 native/landlock-run/scripts/verify-entry-lib.mjs:确认构建产物lib/存在; - native/landlock-run/scripts/verify-packed-install.mjs 从打包后的 tarball 预演完整消费者路径:载荷检查、临时安装、安装后二进制与工作区构建逐字节对 pin、可执行性检查、并通过已安装的启动器做一次真实限制验证——不可执行或缺失的二进制在这里响亮地失败,而不是伪装成“内核不支持”。
- 平台包
- 无安装期回退:入口包没有 install 脚本、绝不在消费者主机上编译(packaging.md 的 “No install fallback”)。若存在编译回退,就会要求所有主机都有 musl 工具链,把干净的 fail-closed 降级变成依赖环境的“也许”。
verify-packed-install.mjs中的打包清单检查强制了这一约束。
对消费方(如 deepseek-harness 的 sandbox 能力)而言,正确的集成姿势是:调用launcherPath()拿到路径 →probe()得到三态结论 → 仅在full/partial时用grantArgs()组装--ro/--rw授权并 spawn 命令;unusable时直接走自己的失败关闭逻辑。完整调用示例见 native/landlock-run/README.md 的 Usage 一节。
小结
landlock-run的支持矩阵用最小的平台集合(linux-x64 / linux-arm64)换取了最高可信度:每个二进制都由原生 runner 构建并被逐字节验证,静态 musl 保证跨发行版通用,功能探测而非版本号决定full/partial/unusable三态,而刻意不支持的平台与缺失二进制共享同一条unusable → fail-closed降级路径。理解这张矩阵,就是理解该包族“宁可关闭,不可带病运行”的边界哲学。
【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考