
cua-driver 的 Linux Nix 测试布局可复现构建、NixOS VM 策略校验与单一行为事实源【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua本篇技术指南聚焦开源仓库 cua 中 nix/cua-driver/tests/README.md 所定义的Linux Nix 检查check布局它描述了 Nix 表达式按“各自证明什么”分组的三个测试入口rust-unit.nix、policy-yaml.nix、policy-rego.nix并明确了 Nix 在测试栈中的职责边界。读完本文你将理解 cua-driver 的 Rust 二进制如何在 Nix 可复现环境中完成无桌面会话的单元/编译检查如何在 NixOS 虚拟机中通过 stdio 的 MCP JSON-RPC 校验 YAML 与内嵌 Rego 权限策略的强制执行以及为什么“桌面行为目录”刻意不出现在 Nix 中、而是统一由类型化 Rust 测试框架作为唯一事实源。一、背景Nix 在 cua-driver 测试栈中的两种职责cua-driver 是仓库中基于 Rust 实现的跨平台 MCP 服务器cua-driver二进制通过 stdio 提供 40 个工具覆盖屏幕捕获、鼠标键盘输入、窗口管理与基于无障碍能力的元素交互见 package.nix。在它的测试栈中Nix 承担两种职责见 nix/cua-driver/README.md可复现的 Linux 构建从锁定的 Rust 源码构建发布用 Linux 包桌面会话依赖供给为“权威的”Rust 类型化测试框架提供桌面会话与运行环境。这两条主线决定了 tests 目录下的文件如何组织。二、检查布局总览每个 Nix 表达式“证明什么”原文档以一张路径-角色表给出了 tests 目录的分工这是整个布局的核心骨架PathRolerust-unit.nixSource-built Rust workspace checks without a desktop sessionpolicy-yaml.nixNixOS VM stdio checks for YAML allow, deny, and argument constraintspolicy-rego.nixNixOS VM stdio checks for embedded Rego policy evaluation三个文件均位于 nix/cua-driver/tests/并在仓库根 flake.nix 的checks属性集中注册为三个 flake checkchecks { cua-compositor-build cuaCompositorPackage; cua-driver-build cuaDriverPackage; cua-driver-linux-rust-unit import ./nix/cua-driver/tests/rust-unit.nix { inherit pkgs; src rustTestSrc; sourceSubdir rust; }; cua-driver-policy-yaml import ./nix/cua-driver/tests/policy-yaml.nix { inherit pkgs; cuaDriver cuaDriverPackage; }; cua-driver-policy-rego import ./nix/cua-driver/tests/policy-rego.nix { inherit pkgs; cuaDriver cuaDriverPackage; }; };flake 针对x86_64-linux与aarch64-linux两个系统各构建一套因此一次nix flake check即可覆盖两个架构的上述全部检查。三、rust-unit.nix无桌面会话的源码级 Rust 工作区检查rust-unit.nix 的目标是在 Nix 的可复现构建环境中验证 Rust 源码与测试工具链本身而不依赖任何正在运行的桌面会话。3.1 与package.nix刻意分离文件头注释明确了两者分离的原因发布用的 daemon 包package.nix必须保持与显示器无关display-independentdoCheck false而这个 check 则专门负责在 Nix 构建环境里运行测试。两者读版本的方式一致——都从Cargo.toml的workspace.package.version通过pkgs.lib.importTOML读取单一事实源避免版本号漂移。3.2 关键实现细节源码子目录通过sourceSubdir默认null与postUnpack把 flake 传入的rustTestSrc定位到rust子目录Cargo.lock 同样取自${rustSrc}/Cargo.lock保证依赖完全锁定测试范围cargoTestFlags覆盖cua-driver、cua-driver-core、cua-driver-testkit、platform-linux四个 crate并附带--all-targets同时构建与运行所有目标含集成测试依赖注入nativeBuildInputs需要pkg-config、rustPlatform.bindgenHook与clang供 bindgen 生成 libpipewire/libspa 的 SPA pod 代码buildInputs提供 X11 栈libx11/libxi/libxtst/libxext以及 Wayland 对等能力所需的pipewire与libei默认测试集是“无头”的注释强调默认 Cargo 测试集合刻意不启动桌面被 ignore 的桌面矩阵由手动 Linux e2e 工作流运行而不是隐藏在 Nix 中。这与package.nix中“默认关闭测试、只构建二进制”的定位形成互补包要轻量可发布check 要尽量充分验证源码。四、policy-yaml.nix在 NixOS VM 中校验 YAML 权限策略policy-yaml.nix 使用pkgs.testers.runNixOSTest启动一台 NixOS 虚拟机在 VM 内完成MCP stdioJSON-RPC 2.0 over stdio的端到端权限校验。4.1 测试策略文件VM 内的测试命令首先写入/tmp/policy.yamlallow: tools: - screenshot rules: - tool: click constraints: x: { min: 0, max: 1920 } y: { min: 0, max: 1080 } deny: tools: - type_text这份 YAML 演示了策略文件的核心语法allow.tools是无条件放行的工具列表allow.rules是带参数约束的条件放行规则deny.tools是显式拒绝的工具列表。4.2 启动 daemon 并等待就绪以CUA_DRIVER_POLICY_FILE环境变量指向策略文件启动cua-driver serve并轮询cua-driver status --socket最多 200 次、每次间隔 0.05s确认 socket 就绪后才开始发请求env \ CUA_DRIVER_POLICY_FILE/tmp/policy.yaml \ CUA_DRIVER_RS_TELEMETRY_ENABLEDfalse \ cua-driver serve --socket $socket --no-permissions-gate --no-overlay \ /tmp/daemon.log 21 注意此处同时关闭了 telemetry、permissions-gate 与 overlay让测试聚焦于策略引擎本身。4.3 通过 stdio MCP 断言四类行为测试通过 coproc 建立cua-driver mcp --socket子进程用printf写入 JSON-RPC 请求、read读取响应再用jq -e严格断言initializeid 1 and .result ! nullMCP 握手成功tools/call screenshoterror null and .result ! null白名单内的工具正常执行tools/call type_text返回isError true且content[0].text以Permission denied:开头——验证deny.tools显式拒绝tools/call clickx1921 越界同样返回Permission denied:——验证allow.rules中的数值范围约束x超出0..1920被强制执行。这四步恰好覆盖了 YAML 策略的放行、显式拒绝与参数约束三种决策路径。五、policy-rego.nix内嵌 Rego 策略引擎的 VM 校验policy-rego.nix 与 YAML 测试结构几乎一致区别在于把策略文件替换为一个Rego 策略目录验证驱动内嵌的 Rego基于regoruscrate见 policy.rs评估能力。5.1 目录形式的策略测试在/tmp/policy下写入两个.rego文件同一package cua.policy# base.rego —— 默认拒绝 package cua.policy default allow false# tools.rego —— 放行与条件放行 package cua.policy allow if input.tool screenshot allow if { input.tool click input.arguments.x 0 input.arguments.x 1920 input.arguments.y 0 input.arguments.y 1080 }CUA_DRIVER_POLICY_FILE指向目录/tmp/policy而不是单个文件。从源码看PolicyEngine::load 会判断路径是目录还是文件目录只收集.rego文件policy_files按文件名排序单文件则依据扩展名.yaml/.yml/.rego选择引擎。5.2 Rego 求值的输入结构每次工具调用时引擎收到如下input{ server: cua-driver, tool: click, arguments: { x: 2000, y: 100 } }策略只须实现data.cua.policy.allow规则并返回布尔值evaluate对allow求值得到true即放行false或Undefined即拒绝错误信息为tool ... is not allowed by the Rego policy。测试断言x2000超出 1920 上限的click与type_text都被拒绝而screenshot被放行。5.3 两个 VM 测试的共同模式都通过pkgs.testers.runNixOSTest声明nodes.machine注入cuaDriver与jq两个 system packages都用builtins.toJSON把 bash 测试命令安全嵌入machine.succeed(...)都在EXITtrap 中清理 daemon 与 coproc 进程保证 VM 退出时不留孤儿进程。六、源码级佐证策略引擎如何支撑这些检查NixOS VM 测试所断言的“拒绝”行为其底层实现在 cua-driver-core/src/policy.rs环境变量入口CUA_DRIVER_POLICY_FILEPOLICY_FILE_ENV第 11 行与管理员层级的CUA_DRIVER_MANAGED_POLICY_FILE策略一旦配置路径缺失属于配置错误而非隐式关闭missing_configured_policy_prevents_daemon_startup测试断言 daemon 直接拒绝启动见 permission_policy_startup_test.rs默认拒绝YAML 策略对未列出的工具返回Deny单元测试yaml_is_deny_by_default显式deny优先于allowexplicit_deny_overrides_allow约束类型规则约束支持min/max数值、max_length/pattern字符串与allowed枚举值见RawConstraint定义第 542-550 行与Constraint::matches的求值逻辑第 634-677 行工具名规范化type_text_chars会被规范化映射为type_text后再评估canonical_tool_name第 133-138 行因此 VM 测试中deny: tools: [type_text]同样拦截底层字符级输入工具双层策略交集authorize_tool_call第 298-311 行把 managed 层与 user 层求交集用户策略只能收窄、不能放宽管理员上限单元测试managed_and_user_layers_are_intersected进程内不可变快照策略经 SHA-256 内容指纹policy_sha256在加载时一次性固化OnceLock保证 stdio 与 HTTP 请求共享同一份不可变策略快照第 146-148、226-231 行。这些机制正是两个 NixOS VM 检查能稳定断言“Permission denied”的前提。七、为什么 Nix 中没有“桌面行为目录”原文档特意强调本目录刻意不包含桌面行为目录desktop behavior catalog。Nix 构建驱动、单元检查、会话依赖与可选的 compositor 包规范的 GUI 场景与断言位于类型化 Rust 测试框架中。父级 READMEnix/cua-driver/README.md进一步说明原因旧的 NixOS Python 客户端、GIF 场景、真实应用冒烟矩阵与 compositor 矩阵被移除是因为它们维护了第二套断言不同的场景目录权威 Rust 矩阵才是覆盖范围的事实源退役条目只有在当前类型化用例证明了同一契约时才被视为等价。因此新增用户行为覆盖的路径是先进入 Rust 测试框架例如 cua-driver-testkit/src/raw.rs 的RawDriver这类类型化驱动测试工具Nix check 可以负责提供会话与包环境但必须调用共享的 Rust 目录而不是再定义第二套行为断言。这一点保证了行为契约单一来源、避免断言漂移。八、如何在本地运行这些检查在仓库根目录flake.nix 所在位置可直接运行# 运行全部 flake checks含上述三个检查 nix flake check # 单独运行某个检查 nix build .#checks.x86_64-linux.cua-driver-linux-rust-unit nix build .#checks.x86_64-linux.cua-driver-policy-yaml nix build .#checks.x86_64-linux.cua-driver-policy-rego需要说明的是policy-*.nix两个检查依赖 NixOS VMrunNixOSTest需要宿主具备运行 VM 的能力rust-unit.nix则只要求在 Nix 可复现环境中编译并运行无头 Rust 测试。若要在真实桌面会话下运行权威 Wayland 矩阵父级 README 提供了显式入口nix develop .#cua-driver-wayland-e2e -c \ scripts/ci/linux/run-rust-e2e-wayland.sh该包装器会启动一个禁用 Xwayland 的纯 Wayland Sway 会话然后调用与 X11 共用的同一套规范 Rust runner结果遵循统一 JSONL 模式并把 MP4 轨迹保留在artifacts/cua-driver/linux/下。九、小结nix/cua-driver/tests/的布局遵循一条清晰的设计原则Nix 负责“可复现地构建与验证策略引擎”Rust 类型化测试框架负责“定义全部桌面行为契约”。rust-unit.nix守住无桌面会话下的源码与测试链完整性policy-yaml.nix与policy-rego.nix则把 YAML 与内嵌 Rego 权限策略放进 NixOS VM 中做端到端 stdio MCP 校验。理解这一布局有助于你在为 cua-driver 贡献测试时把“会话与包环境”和“行为断言”放在正确的位置新行为先进 Rust 目录Nix 只负责提供环境。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考