# M0 技术验证计划 ## 1. 目的 M0 不开发完整产品,只验证会导致架构失败的技术假设。每项实验必须提供可运行代码、环境记录、指标和明确结论。 ## 2. 通用要求 每个实验目录包含: ```text spikes// ├── README.md 假设、环境、运行方法 ├── src/ ├── tests/ ├── results/ 脱敏日志与指标,不提交大视频 └── decision.md pass/fail/follow-up ``` 通过标准不能用“看起来流畅”。至少记录版本、CPU/GPU、驱动、分辨率、帧率、复制路径、延迟和资源占用。 ## 3. Spike A:IronRDP 目标:判断 IronRDP 能否作为正式 Windows RDP Adapter。 场景: - Windows 11 Pro 本地账户和 NLA。 - Windows Server。 - 正确/错误密码、证书首次连接和证书变化。 - 自动跟随、1920x1080、4K、自定义尺寸和连续动态 resize。 - 键盘、Unicode、鼠标、剪贴板和音频。 - 断线、锁屏、注销和重连。 - TCP 与 RDP UDP multitransport。 通过标准: - NLA/TLS 稳定连接,无敏感日志。 - 图形更新可获得 dirty rect 并持续运行 2 小时。 - 动态 resize 不要求重建整个客户端。 - 服务端不支持 Display Control 时能明确提示并通过确认后的重连应用初始尺寸。 - 中文输入和文本剪贴板可用。 - 明确确认 UDP multitransport 是否支持以及限制。 决策: - 全部核心项通过:进入内嵌 RDP MVP。 - 仅音频/多显示器等非核心项缺失:记录阶段性限制。 - NLA、图形或网络恢复不通过:MVP 使用 mstsc Adapter,IronRDP 保持实验模块。 ## 4. Spike B:Native Helper 与 D3D11 目标:验证 Tauri 主程序可以安全管理独立 Rust/D3D11 helper。 场景: - 启动/退出/反复重启 RDP 和 native-video helper。 - 在 Windows 实机验证 RDP viewer Named Pipe 的当前用户 SID ACL、拒绝远程客户端、单实例、一次性 key/nonce、协议版本、OS PID/创建时间/镜像 hash 和 challenge MAC;验证伪造客户端及篡改载荷均被拒绝,并验证控制服务崩溃时 Job Object 回收 viewer。 - Helper 原生窗口 resize、最小化、恢复和全屏。 - 100/125/150/200% DPI。 - 在不同 DPI 显示器间移动。 - Raw Input、焦点、光标捕获和相对鼠标。 - D3D11 device lost 模拟。 - 默认 GPU、手动 GPU、GPU 缺失和跨显示器 Adapter 变化。 通过标准: - Helper 与 Tauri 主窗口生命周期彼此隔离。 - DPI 变化后像素和输入坐标一致。 - IPC 不携带 frame,凭据不进入命令行。 - Helper crash/device lost 后主程序可诊断并重启。 - 手动选择失效时本次回退默认,不改写保存配置。 ## 5. Spike C:Native Video 目标:验证客户端 D3D11 解码到呈现的零拷贝路径。 默认 Native 管线: ```text webrtcbin -> H.264 depay/parse -> D3D11 decoder -> GstD3D11Memory -> d3d11videosink ``` 场景: - 软件测试源与真实 Linux Agent 源。 - 720p/1080p/1440p/4K,30/60 fps。 - Intel/NVIDIA/AMD 至少覆盖可获得的硬件。 - Native 会话、WebRTC stats 和 GPU process failure。 - pipeline pause/resume/rebuild。 - Native helper window resize/destroy。 - 显式 compatibility 下硬件解码失败后的软件回退;严格模式验证拒绝。 - 同显示器 Adapter 零拷贝与跨 GPU 复制诊断。 - `required_end_to_end` 默认选择 native helper,无法验证 D3D11 surface 路径时拒绝而不是静默回退。 通过标准: - Native 路径保持 D3D11 memory,不发生持续 GPU→CPU→GPU 往返。 - 1080p60 连续 4 小时无队列和内存增长。 - 窗口关闭后 pipeline 完整释放。 - 黑屏、解码失败和插件缺失能返回结构化错误。 - 分辨率切换不重建认证/控制通道,旧 generation 不会覆盖新尺寸。 - 每次 GPU、显示器或分辨率切换都会使旧零拷贝证明失效,并在新 generation 上完成双端重新验证。 ## 6. Spike D:Wayland Agent 目标:验证自研 Agent 可以通过标准 Wayland 接口控制当前会话。 场景: - GNOME 与 KDE Plasma Wayland。 - Portal 接受、拒绝和取消。 - 单/双显示器、动态拓扑。 - 调整编码分辨率并确认 Wayland 实体显示模式不变。 - PipeWire DMA-BUF 与内存帧。 - DMA-BUF -> GPU conversion/scale -> hardware encoder 全程无 CPU map,并验证 buffer/fence 生命周期。 - libei 键盘、绝对/相对鼠标。 - 锁屏、注销和恢复令牌。 通过标准: - 用户授权后可稳定捕获和输入。 - 拒绝授权不会隐蔽降级。 - 注销后所有资源释放。 - 每个桌面环境输出能力矩阵,不笼统声明无人值守。 - `required_end_to_end` 在 DMA-BUF 导入失败时返回 `CAPABILITY_ZERO_COPY_UNAVAILABLE`;只有显式 compatibility 才测试 memory-frame 回退。 ## 7. Spike E:Xorg Agent 目标:验证 Xorg 与 Wayland 共用媒体和输入模型。 场景: - XComposite/DRI3 导出 DMA-BUF,XDamage 跟踪变化。 - 显式 compatibility 下的 XShm/XImage 性能回退。 - XRandR resize/多显示器。 - 调整编码分辨率并确认未调用 XRandR 改变实体显示模式。 - XTest 键鼠和中文输入。 - 错误 Xauthority 和不同 UID。 通过标准: - 当前用户会话可达到 1080p60。 - 静态桌面依靠 damage 降低捕获工作量。 - 不使用 `xhost +` 或复制其他 UID Cookie。 - 无权限时明确失败,不尝试 root 绕过。 - DRI3 到硬件编码器无 CPU/cross-GPU copy;XShm/XImage 不报告零拷贝且不能进入默认会话。 ## 8. Spike F:Web 终端 目标:验证 xterm.js 与 Linux PTY/DataChannel。 场景: - bash/zsh,UTF-8 和中文宽字符。 - `vim`、`top`、`tmux` 等全屏程序。 - resize、SIGINT、退出码和断线恢复。 - 高频输出和输出环形缓冲区溢出。 - WebView reload/crash 与会话恢复。 - PAM 拒绝、账户过期和 UID 0。 通过标准: - 普通用户身份、组、HOME、SHELL 与本地登录一致。 - 不能直接创建 root shell。 - 全屏 TUI、颜色、光标和中文显示正确。 - OUTPUT_GAP 明确显示,内存保持有界。 ## 9. Spike G:差网络 目标:验证自适应策略不是静态配置。 使用 Linux bridge 和 `tc netem` 注入: - 1/3/5/10/15% 随机丢包。 - 突发丢包、重排和重复包。 - 30/100/250/500 ms RTT。 - 20 Mbps → 2 Mbps → 20 Mbps 带宽阶跃。 - 3~10 秒完全中断。 通过标准: - TWCC/GCC 指标能被 Rust quality-controller 消费。 - 编码码率可以不中断 pipeline 动态更新。 - 5% 丢包不主动断开,输入保持可用。 - 10% 突发丢包后能降档并通过 PLI/IDR 恢复。 - 文件拥塞不阻塞输入/心跳。 - 恢复后逐级升档,不持续振荡。 ## 10. Spike H:配对与权限 目标:验证设备身份、票据和进程边界。 场景: - 首次配对、本机确认和取消。 - 错误/过期配对码与失败限速。 - 客户端撤销、权限修改和 authorization epoch。 - Ticket 过期、重复、跨客户端和跨 UID 使用。 - Unix Socket 假冒进程。 - agentd 启动 desktop/shell session 后完成降权。 通过标准: - 未配对客户端无法创建会话。 - Ticket replay 被拒绝并审计。 - 撤销后现有会话终止,旧 Ticket 失效。 - agentd 不读取媒体或终端内容。 - shell-session 权限下降自检通过。 ## 11. Spike I:边缘中继 目标:验证传统缓存 CDN 之外的实时边缘路径。 场景: - 单 coturn POP 的 UDP/TCP/TLS。 - Rust Rendezvous 转发 Agent 出站连接与客户端签名请求。 - 短期 TURN credential 过期、跨 session 和配额校验。 - Direct 成功、Direct 失败后 Relay、Relay 故障后 ICE restart。 - Direct 可用但质量差时选择 Client POP -> 骨干 -> Agent POP。 - IronRDP 通过透明 L4 Edge Connector 连接 Windows RDP TCP/UDP。 - 控制面停止后的已有会话。 通过标准: - 智能优选在 Direct 明显更优时不误走 Relay,在 Dual Edge 更优时不固守 Direct。 - TURN 路径保持端到端 DTLS-SRTP/DataChannel 加密。 - 双 POP 路径能够证明使用供应商内部/优质骨干而非普通公网绕行。 - UDP 禁用时可以通过 TURN TLS 443 建立。 - 凭据重放和跨 session 使用被拒绝。 - 已建立会话不因 Rendezvous 停止而中断。 - RDP Edge 保持目标证书/NLA 身份,UDP 不进入 TCP 队头阻塞。 ## 12. 集成切片 各 Spike 通过后只合并一条最窄端到端路径: ```text Windows Tauri Client -> pair with Linux Agent -> create Wayland session -> WebRTC H.264/Opus -> native-video D3D11 zero-copy helper -> mouse/keyboard DataChannel -> disconnect and release ``` 该切片不包含文件、复杂剪贴板或多显示器。连续运行与资源释放通过后,再进入 M1/M2 产品化。 ## 13. 输出物 M0 结束必须交付: - 九项 Spike 的 decision.md。 - 依赖与许可证初始清单。 - 协议 v0 capability 和错误码。 - Windows/Linux 测试环境镜像说明。 - 性能基线与网络退化报告。 - 关键限制和回退 Adapter 决策。 - 更新后的 M1~M3 范围。 任何关键 Spike 没有结论时,不进入大规模 UI 和业务功能开发。