# 未提交测试 Review 报告:假测试与实现语义核查 > 审查对象:工作区全部未提交改动(HEAD `800011ef7`,2026-09-20 快照; > 63 个修改文件 + 11 个新测试文件,+38180 / −254 行)。 > 审查重点(用户指定):**假测试**、**修改实现语义以匹配测试的行为**。 > 报告落笔:2026-09-22。配套计划文档:[`test-coverage-90-80.md`](test-coverage-90-80.md)。 > > 标注约定:**[实证]** = 审查会话直接核对过代码原文/手算过数值; > **[子代理]** = 深查子代理报告、审查会话抽样复核过关键链条。 ## 0. 结论摘要 **问题一:是否修改了实现语义以匹配测试?——未发现。** 全部 254 行删除/修改逐条核对:生产侧改动要么是有设计文档回填的 M5 零拷贝功能开发,要么是与文档契约对齐的**真 bug 修复**(`ForceParams` 默认值、`clip.rs::store_output_image`),没有一处是"为了让测试通过而 扭曲实现"。 **问题二:是否存在假测试?——大部分是真测试,但确认 4 组高危 + 10 项中危。** 最严重的不是传统意义的"无断言测试",而是两类更隐蔽的模式: 1. **测试固化既有实现缺陷**:约 12 个 `undocommands_test.rs` / `graphops.rs` 测试把 `block.rs` setter 语义互换缺陷的反向行为 (roll 不 roll、slide 不 slide、负时间线坐标、块重叠)写成精确期望值 (§3.1)——测试向实现投降,而非实现向契约收敛。 2. **"环境容忍"逃逸路径**:`Ok|Err` 双向接受、饥饿即跳过、CI 恒跳过 (§3.2–§3.4)——产品回归与环境污染不可区分,验收测试在门禁 job 里静默空转。 统计:高危 4 组(含 1 个活的产品缺陷)、中危 10 项、低危约 12 项; 正面确认(合格项)9 项,见 §6。 ## 1. 审查范围与方法 - **删除行全查**:`git diff` 的 254 行删除是既有实现语义变更的唯一可能 载体,逐条核对并手算验证数值等价性(§2)。 - **新测试文件全文审查**:11 个 untracked 测试文件(约 6300 行)由三个 深查子代理全文通读,审查会话对全部高危论断做了原文复核。 - **内联测试**(约 3 万行新增):模式扫描(静默 return、`let _ =` 丢弃 结果、`#[ignore]`、sleep、同义反复 matches!、Ok|Err 全收)+ 高风险区 抽样精读(`eval.rs`、`ffmpeg.rs`、`worker.rs`、`instance.rs`、 `history.rs`、`dialogs.rs`、`controls.rs`)。 - **交叉验证**:与 `test-coverage-90-80.md` §7.5 六批自述、 `render-pipeline-threads.md` M5 回填逐条对账;CI 配置 (`.github/workflows/ci.yml`)核对跳过条件在门禁 job 上是否成立。 - 未重新运行测试套件(计划文档声称 3069 passed / 0 failed;静态审查 未发现与该声称矛盾之处)。 ## 2. 生产语义核查:全部 254 行删除的定性 | 改动 | 定性 | 证据 | |---|---|---| | `oak-core/backend.rs`:YUV 矩阵常数(`65535/56064` 等)删除 | **合法泛化** [实证] | 新 `from_matrix_depth` 在 16-bit 下与旧常数逐位一致(`ay = max/(y_white−y_black) = 65535/56064`;full-range 分支 `(1.0, 0.0, 1.0, 32768/65535)` 亦一致),为 M5 NV12/P010 平面导入服务 | | `oak-codec/hwdecode.rs`:Linux 设备顺序 CUDA 优先 → VAAPI 优先 | **有意行为变更** [实证] | CUDA/NVDEC 表面无公开句柄导出,零拷贝只能走 VAAPI DMA-BUF;`render-pipeline-threads.md` M5 回填记录了真机(RTX 5070 Ti + nvidia-vaapi-driver)验证 | | `oak-codec/ffmpeg.rs`:hw transfer / 色彩范围判定 / 帧缓存删除 | **等价重构 + 真修复** [实证] | 范围判定抽成 `frame_colorimetry`(force 优先、YUVJ 判定、`AVCOL_RANGE_JPEG` 分支逐一保留,CPU/GPU 两路共享);`RefFrame`(`av_frame_ref` 语义)修复 ffmpeg-next `Video::clone` 用 `av_frame_copy` 深拷、丢失硬件表面引用(克隆 VAAPI 帧 transfer 报 EINVAL)的真 bug | | `oak-task/render.rs`:`ForceParams` 去 derive、手写 `Default` | **真 bug 修复** [实证] | `derive(Default)` 给出 `force_format = 0`(= `PixelFormat::U8`),违反文档契约 `-1 = off`,会把 F32 管线推向 U8 并在 footage 帧上 panic;测试断言的是文档契约(`render_test.rs:348-351`,注释明示 "not 0 = U8"),非实现现状 | | `oak-plugin/clip.rs`:`store_output_image` 重写 | **真 bug 修复** [实证] | 原实现把像素写入 `texture_get_frame` 的深拷贝,CPU 纹理的插件输出被静默丢弃;现在 CPU 直接回写 `f.data`、GPU 走 upload、Planar 显式报错,与 `render_driver::write_output_frame` 既有修复一致 | | `oak-render/eval.rs`:`DECODED_FRAMES` LRU 值类型 `Frame`→`Texture`、`render_footage_frame_inner`→`_opts(allow_import)` | **M5 功能** [实证] | planar 条目独立上限 4(硬件表面驻留约束);resolve 失败按帧回退 CPU staging(解码器会话缓存兜底,不重解码) | | `oak-render/pipeline.rs`:`DecodeRequest.allow_import` | **M5 功能** [实证] | montage 合成器(CPU 消费者)`false`、footage 路径 `true`,且入缓存键——正面落实计划 §5.2 "staged 请求不得命中导入缓存" 的 M5 审计项 | | `oak-app/dialogs.rs` 测试期望 180→184 | **合法期望修正** [实证] | 高度 SpinBox 的 `SliderModel`(gpui_widgets)以 step=8、min=120 建网格,180 恰在 176/184 中点、向上吸附;控件自身测试已固化 "snapped to the model's step" 契约(`controls.rs:1654/1720`) | | `oak-app/oakui/real.rs` / `worker.rs` / `node_factory.rs` / `ofx.rs` 删除行 | **测试改写**,见 §3.3 / §6 | 回放验收测试弱化(高危);其余为等价重构或断言保留 | **流程问题**:M5 功能开发(`gpuinterop.rs`、`backend/external.rs`、 `PlanarTexture`、hwdecode 顺序)与六批覆盖率测试**混在同一未提交工作 区**。计划 §9 承诺"覆盖率改造不得引入行为变更",混提使该不变量无法被 review 验证——本次是人工逐行核对全部删除行才得出"功能与测试可分离" 的结论。建议分开提交。 ## 3. 高危问题(合并前应处理) ### 3.1 🔴 undopointer 族测试固化了一个活的产品缺陷 [实证 + 子代理] **根因**(已提交代码,本次 diff 未改动):`oak-node/src/block.rs:93-107` 的 `set_length_and_media_out` / `set_length_and_media_in` 相对其声称的 C++ parity 语义**正好互换**: ```rust /// Set the length, keeping the media out anchored (C++ /// `Block::set_length_and_media_out`): ... pub fn set_length_and_media_out(&mut self, length: Rational) { let out = self.in_() + self.length(); self.range = TimeRange::new(out - length, out); // ← 实际锚定 OUT、移动 IN self.media_in = self.range.in_(); // ← 时间线 in 写进 media_in(坐标空间混淆) } ``` C++ Olive 的 `set_length_and_media_out` 是 IN 锚定、OUT(及 media_out) 移动。该互换同时违反三处成文契约:block.rs 自己的 C++ parity 注释、 `oak-timeline/src/common.rs:39`("`k_trim_out`: trim the out point")、 `graphops.rs:2703-2707`(roll_edit 文档:"the boundary moves without disturbing anything else")。附带缺陷:`media_in := range.in_()` 把媒体 入点写成时间线入点;真锚定 media_out 应为 `media_in = media_out - length`。 **净效果**(`undopointer.rs` 的机械移植在互换后的 setter 上运行): - **roll edit 不 roll**:`undocommands_test.rs:625-648` `block_trim_roll_edit_resizes_adjacent_clip` 断言 first=[0,50)、 second=[50,100) roll 到 25 后得 **first=[25,50)、second=[50,125)** ——接缝 50 纹丝不动,first 的 IN 移动、second 的 OUT 外扩。真 roll 应为 first=[0,25)、second=[25,100)。**无偏差标注**;doc 只描述 "没有插 gap" 这一表层现象。 - **slide 不 slide**:`:736-760` 断言被滑块不动([50,100)),两个邻居 反向膨胀,previous 出现**负时间线入点 [-20,50)**。 - graphops 内联测试(`graphops.rs:6048-6071`)是**自觉固化**:NOTE 明说 "Assert the actual outcome so a future semantic fix has to update this expectation deliberately",并把 `media_in = -2` 写进期望——诚实且有价值 (修复时强制改写),但 NOTE 自身措辞也不准(称锚定 follower 的 OUT, 断言显示其 OUT 从 20 移到 18、锚定的是 IN)。 - 数值例(与 graphops 测试一致):a=[0,10)、b=[10,20) roll 到 12 → a=[-2,10)(负入点、media_in=-2)、b=[10,18),接缝仍在 10,b 尾部反被 截掉 2 秒。若 b 还有后继,会产生块重叠/留洞(`undopointer.rs:160-174` 的补偿 gap 按 C++ 假设放在 `[out, out+diff)`,与实际移动方向矛盾)。 - **缺陷是活的**:`real.rs:4772-4798` 把 UI 事件 `TimelineEvent::ClipRollRequested` 直接接到 `graphops::roll_edit`。 - 仓库内 `undosplit.rs:200-214`、`undoripple.rs:342-358`、 `undogeneral.rs:865-872` 的作者显然发现了互换并做了补偿性选边 + 注释, 唯独 undopointer 的 BlockTrim/TrackSlide 与 undogeneral 的 Resize/InsertGaps 未补偿。[子代理] **加重项** [子代理]: - 4 处测试**恰好省略了唯一能暴露矛盾的断言**:`:593-620`(gap=[50,75) 与 second=[50,100) 重叠,只断言序号不断言 span)、`:653-708` 两处 (被 trim 块 redo 后实为 [-25,50),不断言)、`:861-889`(gap 与 tail 重叠,tail 只断言 id)。 - **全文件(1488 行、38 测试)无一处断言 trim/slide/ripple/split 后的 media_in**,夹具一律 media_in=0、timeline in=0,使两个内容损坏缺陷 不可见:(a) `media_in := range.in_()`;(b) `undoripple.rs:342-346` splice 修剪不动 media_in——删除 [25,50) 后余块 [25,75) 实际播放**被删 内容**而非后移内容。 - `:565-588` 普通 trim 测试的注释把反转当规范写("Trim-out is out-anchored: the clip's in shifts to 25"),与 `common.rs:39` 直接 矛盾,会误导后来者。 - `:1108-1122` ResizeWithMediaIn:注释说 "keeping the out point fixed", 断言却是 in 锚定、out 移动;实现与命令名 `WithMediaIn` 及其 doc (`undogeneral.rs:105-107`)相反。 - `:1173-1216` InsertGaps 两测试:既有 gap 向左生长越过插入点并与前块 重叠,注释把左向生长表述为预期,而 `undogeneral.rs:866-872` 在另一 命令里明说 out-anchored "would push the in point negative"。 **定性**:作为产品缺陷 **高**(指针编辑族整体反向 + 负坐标 + 重叠 + 内容损坏,挂在真实 UI 路径);作为测试问题 **中-高**(graphops 一处是 诚实的 characterization test;undocommands_test 多处无标注固化且回避 关键断言)。计划文档第四批"记录(未改生产代码)"只登记了 roll_edit 一条,实际波及面大得多。 **修复顺序建议**:先补 `RippleInfo` 公开构造器与 media_in 断言维度,再 统一裁决 block.rs:93-107 的语义互换,届时上述期望值按 graphops NOTE 的 意图 "deliberately" 改写。 **裁决(2026-09-24,已修复)**:准备项落地后按 §9 的三原语方案完成语义 修复,全部 KNOWN-SWAP 期望已按正确几何改写,并补上 `media_in` 与 "缺口后的块不受影响"回归断言(详见 §9 §3.1)。 ### 3.2 🔴 `oak-task/tests/render_test.rs:932-951`:全批次唯一"永不失败"的测试 [实证] `private_dispatcher_renders_frames_and_audio_through_workers` 对两次真实 渲染的结果做双向接受: ```rust match outcome { Ok(()) => { /* 真断言:order、size、audio */ } Err(error) => { eprintln!("private dispatcher worker render unavailable: {error}; skipping"); } } ``` `f32_outcome` 同构。Err 分支不区分**环境缺失**(worker 池起不来)与 **产品失败**(`"Frame render ticket failed"`、`shm_frame_to_texture` 的 BGRA8/F32 转换回归、poll pump 超时、解码失败)——全部放行。一旦 worker 二进制存在,本测试**不可能失败**,恰好掩盖它名义上要测的 ShmFrame/ ShmAudio 交付缝与 dispatcher teardown 的任何回归。 叠加 `:881-884` 的"缺二进制即 return"(`locate_oak_worker` 依赖 `target/{debug,release}/oak-worker` 已存在,而 `cargo test -p oak-task` 不构建同 workspace 的 oak-worker 二进制):定向运行/干净 CI 下长期静默 跳过,私有 dispatcher 路径**实际覆盖可能为零**——覆盖率数字虚高的典型 来源。 **修法**:Err 分支按错误内容分流——环境性错误(pool 启动失败)才跳过, 产品性错误必须失败;或至少断言 `error` 匹配已知环境错误串。 ### 3.3 🔴 `oak-app/oakui/real.rs`:三个回放验收测试的"饥饿即跳过→通过" [实证] program-window、display、source-window 三个验收测试均新增 `eprintln! + return`(计为 pass)的逃逸路径: - program-window:`pumps == 2000 && filled == 0` 跳过;pump 上限 5000→15000。 - display:`pumps >= 1200 && peak < 0 && slots == 0` 跳过;原"playhead 60→120 间 peak 严格增长"的两点采样断言弱化为"任意时刻 advances > 0 一次";pump 上限 9000。 - source-window:**跳过条件仅 `pumps == 2000`,不检查槽位数**(real.rs 约 :16396)——注释声称 "skip only when the shared pool delivered nothing",但若帧已交付而 `preview_slot_frame` 服务侧有 bug(candidate 存在、hit 恒 None),同样被伪装成池饥饿跳过。program-window 至少有 `filled == 0` 判别,此处没有。 **产品真坏(worker 永远交不出帧)与环境保护不可区分**——验收测试失去 回归守卫功能。计划文档声称"聚焦运行仍严格断言",但**代码里没有任何 机制区分聚焦/全量运行**,该声称不成立。 **复合隐患** [实证]:`WorkerBinGuard`(`real.rs:8044-8056`、 `renderops.rs:3659-3671`)硬编码 `../../target/debug/oak-worker`: - coverage job 的 target 目录是 `target/llvm-cov-target/`,干净环境下 `target/debug/oak-worker` 不存在; - `procpool.rs:2402` `resolve_worker_bin` 对 `OAK_WORKER_BIN` **不检查 存在性**直接采用 → spawn 失败 → 槽位恒空 → 跳过路径必然触发; - 即普通 CI(`cargo test --workspace` 会把 oak-worker 建到 `target/debug`)能真跑,**coverage job 里这组验收测试静默空转**—— 恰好在产出覆盖率数字的那次运行里。 对照:`procpool.rs:2922` 测试侧 `find_real_worker` 对 env 覆盖做了 `p.exists()` 检查,守卫没有。 **修法**:跳过条件补"槽位已交付但未服务→必须失败"判别(source-window 尤其);给严格模式一个真实机制(如 CI 设 `OAK_STRICT_PLAYBACK=1` 时禁止 跳过);`WorkerBinGuard` 改为从 `current_exe()` 推导(与 `find_real_worker` 一致)。 ### 3.4 🔴 CI 门禁 job 上永久跳过的两组测试 [实证] **(a) ICC 门控(`oak-core/color.rs`,17 处跳过)**:`system_icc()` (color.rs:770-783)只探测固定系统路径(macOS ColorSync、Linux colord/ghostscript),而 `ci.yml:46-53` 的 apt 列表**不含任何 ICC 包** → Linux CI(唯一聚合门禁 job)上恒 None → `display_icc_bgra8_never_outputs_black` (文档自称"viewer 黑屏回归守卫")等测试**永久跳过**,只在非门禁的 macOS 周更 job 上真跑。修复便宜:`apt-get install icc-profiles-free` (或 colord),或仓库内置一个小 sRGB ICC 测试资产。 **(b) footage_import(`oak-render/tests/footage_import_test.rs`)** [子代理,关键链条已复核]: CI 是 lavapipe、无 `/dev/dri`,VAAPI/CUDA 设备创建必败且负缓存进程级 粘滞(`hwdecode.rs:197-201`)→ `HW_IMPORTS == 0` → 三个测试恒跳过、 cargo 计为 passed、**零断言执行**。加重项: - `common/mod.rs:61-71` 的 `gpu_context_for_import()` 直接 `?` 返回 None,**绕过了仓库自己的 `OAK_REQUIRE_GPU=1` 硬失败策略**(对照 `backend.rs` 的 `gpu_or_skip`/`shared_gpu_or_skip` 会 panic;同目录 `render_threads_test.rs:776/824` 用的是合规版本); - 计划文档承诺"跳过不等于通过(报告里单列)"**未实现**——无 `#[ignore]`、 无 skip 上报机制,CI 报表里与真跑过的测试不可区分。 测试本体质量不错(见 §6),问题在门禁信号缺失。M5 真机验收已留档 (`render-pipeline-threads-m5-branch-coverage.txt`),但 PR 门禁对该 文件恒零信号,应在 CI 报告侧显式标注(warning annotation)或接入计划 M4 的平台/真机 job。 ## 4. 中危问题 | # | 位置 | 问题 | 标注 | |---|---|---|---| | M1 | `manager_test.rs:164-182` ↔ `manager.rs:84-99` | `init()` doc 声称 "Create the singleton **and register the codec task submitter**",实现只置 `codec_submitter_registered: false`;`register_codec_task_submitter` 全仓库**零生产调用点**(仅 codecbridge.rs:94 定义)。测试断言 `Some(false)` 把矛盾固化为"契约"。结合 codecbridge "submission is synchronous" 的过渡契约,判断为文档过期(或注册逻辑缺失),需裁决 | [实证] | | M2 | `render_test.rs:471-494` | `forced_size_and_format_are_applied`:设置了 `force_format = F32`,断言只有 `recorder.frames == vec![(32,32)]`(尺寸);Recorder 不记录像素格式,format 是否应用到交付纹理**不可证伪** | [子代理] | | M3 | `render_test.rs:621-676` | `clip_effect_chain_is_walked_and_bypassed`:enabled=false 与 true 两分支断言**完全相同**(order、frames);若 `clip_effects()` 回归为完全不收集效果链,测试照过。fixture sanity 只验证测试自建图 | [子代理] | | M4 | `writethrough_test.rs:126-161` | `backend_enabled_by_config_binds_and_round_trips` 名义 "round_trips",但**从不读回 sqlite、不断言 `library.db` 文件存在**;write-through 成功仅以 `last_error == None` 反推。`save_project` 退化为静默 no-op 不可检出 | [子代理] | | M5 | `undocommands_test.rs:528-556` | `RippleInfo` 字段私有且**全仓库无公开构造器** → 只能构造空 info → `ripple()` 在 `is_empty()` 守卫处立即 return → "断言状态未变"**不可能失败**;`TrackListRippleToolCommand` 主体约 125 行对集成测试不可达,行为覆盖为 0。测试注释与计划文档均有诚实标注,但覆盖率数字(oak-timeline 90.1%)因此有误导性。根修:给 `RippleInfo` 加公开构造器 | [子代理,构造器缺失已 grep 复核] | | M6 | `loadotio_test.rs:294-310`、`otio_backend_test.rs:388-401` | 两处 FCPXML round-trip 只断言 `sequence_labels == ["Edited"]`;轨道/块/footage 全丢也过(对照 OTIO 版有完整结构断言) | [子代理] | | M7 | `footage_import_test.rs:165` | 导入 on/off 容差 `max_diff < 0.15`,注释两处声称"the same tolerance the hardware-vs-software decode test uses",实际先例(`oak-codec/src/realmedia_tests.rs:567`,未被本次修改)是 **0.08**——引用失实,容差约为先例 2 倍。测试不空洞(图案通道间距 ≥0.65、逐像素 max、test2 ACEScg 用 0.05 且实测 0.011),但应改注释论证放宽理由(swscale 色度滤波 vs GPU 双线性)或对齐 0.08 | [实证:两处阈值均已 grep 核对] | | M8 | 无断言/弱断言冒烟测试 | `worker.rs:3188` `renderer_create_variants_are_tolerant`(**零断言**,纯"不 panic"遍历);`worker.rs:2391` `renderer_creation_falls_back_or_succeeds_headless`(expect + 丢弃 `has_renderer()` 结果);`instance.rs:2123` `trace_probe_branches`(5 个调用仅 1 个断言);`history.rs` `rows_render_and_interact`(`on_menu(MENU_UNDO/REDO)` 只调用不断言效果,如 undo 后条目数应减少);`writethrough_test.rs:232-244`(零断言 + 依赖不受保护的"无残留 binding"前提)。注释均有坦白,但这正是计划 §8.2 自己警告的"为行数写无意义 case"。CI 有 lavapipe + `OAK_REQUIRE_GPU=1`,本可断言确定结果而非"两种结局都接受" | [实证:前四个已读原文] | | M9 | `footage_import_test.rs:136/145、217/226` | `OAK_GPU_IMPORT` 用裸 `set_var`/`remove_var` 非 RAII:中途 `expect("staging decode")` panic 会泄漏 `"0"`;串行锁下**把后续测试的真失败掩蔽成静默跳过**。同文件(render_threads_test)明明有 `SoftwareDecodeGuard` 先例可仿。另 `remove_var` 不恢复外部预设值 | [子代理] | | M10 | `oak-core/src/backend/external.rs` | 611 行 unsafe 平台 FFI(DMA-BUF/D3D11 handle/IOSurface 导入)**零单测**;唯一覆盖是恒跳过的 footage_import(§3.4b)。计划 M4 的平台门禁 job 未接线 | [实证:grep 无 #[test]] | ## 5. 低危问题(简列) - `render_test.rs:352-355`:configurator 边界段(`set_max_inflight(0/ usize::MAX)` 等)调用后零断言;`max.max(1)` 钳制无公开 getter 可验。 - `render_test.rs:405-428`:名义 "generated **(transparent)** frame" 只断言尺寸,不检查像素透明。 - `import_test.rs:219-220`:断言消息声称 "fails with Cancelled",实际 只 `is_err()`,未 `matches!(Err(Error::Cancelled))`(源码确实返回 Cancelled,测试弱化了它)。 - `codecbridge_test.rs:142/162/185/205`:失败路径仅 `is_err()` 不断言 错误变体/消息,无法区分失败原因(如 bad-output-name 若因 probe 失败 而 err 也会通过)。 - `precache_test.rs:254-282`:doc 声称验证 window/progress configurators,`set_max_inflight(1)`/`set_native_progress_signalling(false)` 设置后零对应断言,其余断言与相邻测试重复。 - `task_test.rs:266-292`:setter/getter 回环、`system_time_ms() > 0`、 结尾无断言的 `emit_progress(2.0)`。 - `writethrough_test.rs:95-105`:null 句柄断言是真的,其后四次 bind/unbind/flush 调用零断言。 - `otio_backend_test.rs:296-317`:三种非法 URI 仅 `is_err()`,不区分 错误原因。 - `undocommands_test.rs:428-487`:ripple 删 gap 仅摘成员关系(util.rs 文档化偏差),时间线净效果为零;删区域后洞从 [60,80) 迁到 [50,70)、 可见时间线无变化——注释只描述机制不评语义。 - `gpuinterop.rs:649-652`:`OAK_GPU_IMPORT` set/remove 不恢复外部预设值 (有 `lock_tests` 守卫,实际风险低)。 - `footage_import_test.rs` `sample()` 未断言 `frame.format == F32` 就按 f32 解释字节(对照 render_threads_test.rs:232 有此断言)。 - `render_test.rs:891-930`:测试中途 `RenderManager::shutdown()` + env 覆盖,恢复在断言之前——render panic 会泄漏全局状态(后续 `render_serial()` 自愈)。 ## 6. 合格项(正面确认,防止误伤) 1. **`render_threads_test.rs` +30/−0 纯新增**(`git diff --stat` 核对): `assert_same_frame` 仍是严格逐字节相等、无容差;计数器期望 (`(6,6,0)`、lru_hits=1/decodes=4)、双侧地面真值图案、时间戳逐帧 断言全部保留。旧 flake 靠**消除解码路径分歧**修复(hwdecode 设备负 缓存进程级粘滞 → 同进程两侧走不同解码路径),不是放宽容差。 2. **`OAK_HWACCEL=0` 软解守卫合规**:该二进制全部 13 个测试第一条语句 都是 `let _lock = lock()`,守卫在锁内设置、drop 逆序先恢复 env 再 放锁;`hwdecode.rs` 每次开流实时读 env,守卫真实生效。代价(记录): 硬解下的管线字节一致性从此无测试,hw/sw 像素等价仅剩 `realmedia_tests.rs:504` 一处(0.08 容差,无硬解机器同样跳过)。 3. **逐字节比对不是"自己比自己"**:inline 与 pipeline 是两条真实执行 机器,两侧用不同文件名隔离 eval/decode 缓存键;footage_import 的 on/off 对比同样用 `fs::copy` 换文件名隔离缓存。 4. **`worker.rs` "needs 16000 bytes" 断言**:只是提取变量重排,未弱化; `node_factory.rs` 曲线 JSON 断言等价重构 + 补 helper 双分支覆盖。 5. **ForceParams 测试断言的是文档契约**(`-1`,注释明示 "not 0 = U8"), 与手写 `Default` 及 doc 完全一致——契约验证,非投降。 6. **codecbridge 真实 conform 测试是真断言**:两通道 `.pcm` 存在 (metadata 失败即 panic)、非空(len>0)、`.working` 已重命名消失; 提交为源码确认的同步路径,无竞态。不足(低):未校验 PCM 字节数 是否等于预期样本量。 7. **loadotio 的 CALLBACK_LOCK 真消除了竞态**:锁覆盖全部回调消费点 (XML 路径测试不持锁是正确的——源码确认不触碰回调);`take()` 一次性消费 + 毒化锁 `into_inner()` 恢复,残留回调会导致后续测试 **响亮失败**(`.expect("loaded project")`)而非静默通过。 8. **`eval.rs` OCIO 内联测试抽查质量高**:真 LUT(红通道加倍)、真 resolve 管线、逐像素数值断言(0.25→0.5、green 不变、alpha 保持); 跳过仅在 OCIO 库缺失时触发,CI 有真实静态 OCIO(`ocio-env.sh` + `OCIO_RS_ENABLE_REAL=1`);GPU 跳过经 `shared_gpu_or_skip` 在 `OAK_REQUIRE_GPU=1` 下硬失败,设计正确。 9. **`ffmpeg.rs` 内联测试抽查合格**:像素格式映射矩阵、声道布局回退、 RefFrame 几何/缓冲共享、打开状态机、跨流检索错误——均有具体期望值。 新测试文件无 `#[ignore]`、无 sleep。 ## 7. 建议行动(按优先级) 1. ✅ **裁决 `block.rs:93-107` setter 互换**(产品缺陷,§3.1):2026-09-24 按 §9 的三原语方案修复,约 12 个期望值按 graphops NOTE 的意图 "deliberately" 改写;`RippleInfo` 公开构造器与 media_in 断言维度已先行 落地(M5)。 2. **消灭"双向接受"**(§3.2):`render_test.rs:932` 的 Err 分支按错误 内容分流,产品性错误必须失败。 3. **修回放验收测试的跳过判别**(§3.3):source-window 补槽位检查; 给严格模式真实机制(CI 设 env 禁止跳过);`WorkerBinGuard` 改从 `current_exe()` 推导。 4. **修 CI 恒跳过**(§3.4):apt 装 ICC 包;`gpu_context_for_import` 尊重 `OAK_REQUIRE_GPU`;实现计划承诺的"跳过单列"(CI annotation 或汇总)。 5. **对齐 `manager.rs::init()` 文档与实现**(M1)。 6. 小修批次:M2/M3 补格式与效果链断言、M4 补读回、M7 改容差注释、 M9 改 RAII、M8 在 CI 断言确定结果、§5 各项。 7. **流程**:M5 功能与覆盖率测试分开提交(§2 末)。 ## 8. 审查局限 - 内联测试约 3 万行,采取"删除行全查 + 模式扫描全查 + 高风险区抽样 精读"策略,未逐行读完;[子代理] 标注项中未注明"已复核"的细节以 子代理报告为准。 - 未重新运行测试套件与覆盖率;文中覆盖率数字引自计划文档 §7.5 自述。 - `block.rs` 互换缺陷的 C++ Olive 原始语义对照基于代码注释与仓库内 其他模块(undosplit/undoripple/undogeneral)的补偿性注释推断,未 直接核对 C++ 源码。 ## 9. 处理记录(2026-09-22) 本报告的高/中危与 §5 条目已按下列状态处理;§3.1 的语义裁决首先按报告 建议延后(准备项先行落地),随后于 2026-09-24 完成修复。 ### §3.1 ✅(2026-09-24 裁决并修复) **已用仓库内 C++ 上游源码核准语义**(此前报告 §8 的局限已解除): - `.cache/olive-upstream/app/node/block/block.cpp`:`Block::set_length_and_media_out/in` 只调用 `set_length_internal(length)`,**从不移动时间线 in/out**; in/out(`in_point_`/`out_point_`)由 Track 的布局(`track.cpp:469-470,514-515,575-579`) 按前后块与长度推导。 - `.cache/olive-upstream/app/node/block/clip/clip.cpp`(非 reverse 剪辑): - `set_length_and_media_out`:`media_in` **不变**(media out 随长度移动); - `set_length_and_media_in`:`media_in += old_length - length`(media out 固定)。 - `.cache/olive-upstream/app/timeline/timelineundopointer.cpp` / `timelineundogeneral.cpp`: `BlockTrimCommand` 的 TrimIn/TrimOut 与 `BlockResize*` 的调用与本仓库一一对应, 因此缺陷只在 Rust 的两个 setter(绝对 range 模型把 Track 布局效果错误地编码进 setter)。 **结论:不是两个函数简单对调即可**。同一 C++ 函数在不同命令里需要不同的净时间线 锚定: | 命令 | 时间线锚定 | media 调整 | |---|---|---| | `BlockResizeCommand` | in 固定、out 移动 | 无 | | `BlockResizeWithMediaInCommand` | in 固定、out 移动 | `media_in += old−new` | | `BlockTrimCommand`(TrimIn) | out 固定、in 移动 | `media_in += old−new` | | `BlockTrimCommand`(TrimOut) | in 固定、out 移动 | 无 | 另有 `TrackSlide`、`TrackListInsertGaps`、`TrackListRippleToolCommand`、multicam 等 调用点与 undosplit/undoripple/undogeneral 的补偿性选边需要一并裁决(2026-09-24 已随修复落地,见下;`TrackSlide`/`TrackListInsertGaps` 的“调用方摆放/ripple” 契约同时记入模块文档)。 **修复落地(2026-09-24)**。存储 range 模型定为三个原语 (`crates/oak-node/src/block.rs`),各调用点按上表逐点选择: - `set_length_and_media_out`:**in 固定、out 移动,media 不动** (Resize / TrimOut / 缺口向右生长); - `set_length_and_media_in`:**in 固定、out 移动,`media_in += old−new`** (ResizeWithMediaIn、splice 的右半、ripple TrimIn); - 新增 `set_length_keeping_out`:**out 固定、in 移动,`media_in += old−new`** (TrimIn 本体与 out 邻块、滑块右侧邻块、ripple trim_in)。 关键点: - `TrackReplaceBlockWithGapCommand` 的“仅后随缺口”分支改为 out 锚定: 原实现把缺口向右生长,会吞掉缺口之后的块——这正是“拖动一个素材影响到 其他无关素材”的实证缺陷。回归断言已补(`domain_test`)。 - `undoripple` 的 trim_out 改为 in 锚定(不再误写 media_in),splice 与 trim_in 现在同步推进 `media_in`(内容损坏修复)。 - `undosplit` 显式写两半的 range 与 media:第二半从切点继续,不再依赖 `range.in_()` 的坐标空间巧合。 - `TrackSlideCommand` 保持“调用方摆放滑动块,命令只处理邻块”的存储模型 契约(文档已注明);`TrackListInsertGaps`/`timeline_ripple_delete_gaps` 的后续块 ripple 仍由调用方负责(C++ 布局的显式替代,未在本次范围)。 - 测试:`domain_test`、`undocommands_test` 的全部 KNOWN-SWAP 期望按上表 “故意”改写(roll 真正移动接缝、slide 无负入点、insert-gaps 向右生长、 ResizeWithMediaIn `media_in=20`),`graphops` 内联 roll 期望同步改写; `phase2_units_test` 按新语义修正并补 `set_length_keeping_out` 断言。 **本批已落地(准备项)**: - `RippleInfo::new(block, append_gap)` + `block()`/`append_gap()` 访问器; `undocommands_test.rs` 新增 2 个真实 info 测试(resize 往返、append_gap 插入/撤销),使 `TrackListRippleToolCommand::ripple()` 主体可达(§M5)。 - 补齐 `media_in` 断言维度:roll-edit、`BlockResizeWithMediaInCommand` 往返; 相关期望值加 **KNOWN-SWAP** 标注(roll、slide、insert-gaps、 ResizeWithMediaIn),语义修复时按标注"故意"改写。 - 修正 `graphops.rs` 内联测试 NOTE 的措辞(follower 锚定的是 IN,不是 OUT)。 ### 高危(其余三项) - **§3.2 ✅**:`render_test.rs` 私有调度器测试的 Err 分支按错误内容分流—— 仅 `Error::Failed` 且消息以 `"render worker pool"` 开头(池创建/启动失败) 或缺少 worker 二进制(`locate_oak_worker` 提前打印跳过)才跳过;产品性错误 (`"Frame render ticket failed"`、shm 转换、时间戳等)一律 panic。管理器/ 环境用 RAII `DispatcherEnvGuard` 恢复,断言前显式 `restore()`;两个交付腿 均断言 `formats == [F32]`。 - **§3.3 ✅**:三个回放验收测试的跳过条件收紧为**零交付**(`filled`/`delivered` 为历史最大值,一旦有过交付就禁用跳过);"交付过但服务/显示从未取用" 走有界 失败上限并打印 `serve_misses` 等诊断。新增 `OAK_STRICT_PLAYBACK=1` 严格模式 (跳过改为 panic,含 `#[should_panic]` 自测)。`WorkerBinGuard` 改用 `renderops::test_worker_bin()` 解析链(已有 env → `current_exe()` 同级 → `target/{debug,release}` 兜底),仅在文件真实存在时设置变量并恢复旧值; `process_backend_preview_path_is_zero_copy` 不再硬编码路径。 - **§3.4 ✅**:CI apt 增加 `icc-profiles-free`;同时给 `system_icc()` 补 Ubuntu 实际路径 `/usr/share/color/icc/sRGB.icc`(实测 5 个 display-ICC 测试真跑,BGRA8 中灰精确为 `[128,128,128,255]`)。`gpu_context_for_import` 尊重 `OAK_REQUIRE_GPU=1`(硬失败),所有跳过路径打印 `SKIP:` 标记;文件头注 记录 lavapipe CI 恒跳过与真机验收出处。 ### 中危 - **M1 ✅(裁决:文档化同步契约)**:证据为 C++ `taskmanager.cpp` 仅创建 管理器、移植版 codecbridge 的 "submission is synchronous" 契约与 `TaskManager::init` 无生产调用点。已把 `manager.rs` 模块/`init`/`shutdown` 文档与字段说明改为"不注册",测试断言 `init` 后未注册、且手工翻标志不会安装 oakcodec 回调。 - **M2 ✅**:`Recorder` 记录 `formats`/首像素;新增生成帧路径的强制 **U8** 测试(可证伪),另断言 F32 腿的交付格式。 - **M3 ✅**:夹具效果从 Invert 换成 **Opacity = 0**;enabled=true 必须全透明、 enabled=false 必须非透明——效果链丢失或忽略 enable 标志都会失败。 - **M4 ✅**:writethrough 往返测试插入 `"Written Through"` 文件夹后写穿,断言 `library.db` 存在且非空,并用全新 `backend().load_project` 读回 uuid 与标记。 - **M5 ✅**:`RippleInfo::new` + `block()`/`append_gap()`,新增 2 个真实 info 测试(resize 往返、append_gap 插入/撤销),`ripple()` 主体可达。 - **M6 ✅**:两处 FCPXML 往返补齐轨道/块/footage/转场偏移断言 (转场居中偏移 `3/8`)。 - **M7 ✅**:容差对齐先例 0.08;真机实测 sRGB 0.00878 / ACEScg 0.01141,注释 改为正确论证(GPU 双线性色度 vs swscale 滤波)并打印实测值。 - **M8 ✅**:`worker.rs` 渲染器变体测试改为结果不变量断言(成功↔`is_open_gl`、 失败↔阶段错误串)、`has_renderer()` 与工厂结果一致、崩溃钩子 env 用 RAII、 一次性告警补并发存活断言;`instance.rs` 的 5 个 trace 调用全部断言返回值; `history.rs` 断言 undo/redo 后 `history_index` 与 `done` 变化(行数按面板 契约保持不变,已在注释说明)。 - **M9 ✅**:`StagingDecodeGuard` RAII + 显式 drop;外部预设的 `OAK_GPU_IMPORT` 值会被恢复。 - **M10 ✅**:`external.rs` 新增测试模块:顶部文档列明未单测的 unsafe 平台体与 对应平台 job;4 个测试覆盖纯映射(Vulkan/IOSurface 格式)、参数校验(DMA-BUF 零尺寸/非平面格式)与 D2 别名视图回归。 ### 低危 / §5 - oak-task:`import_test` 断言 `Err(Error::Cancelled)`;`codecbridge_test` 同时 断言桥接层消息与直接驱动 `ConformTask`/`ProxyTask` 的路径原因; `precache_test` 用真实运行兑现"窗口/进度"声明;`task_test` 观测进度钳制; `render_test` 的配置器边界、透明帧、shutdown 恢复顺序均已修正。 - `gpuinterop.rs`/`footage_import_test.rs` 的 env 泄漏改 RAII(含恢复外部预设)。 ### 追加修复 - **新暴露 flake**:`app::tests::preferences_general_tab_writes_cache_ahead_and_storage` 在满载并行下"点击→按键"焦点交接竞态(1/4 次读到 120)。点击后补一次 effect flush + 一帧绘制再派发按键;通过。 ### 验证 - 各 crate:oak-task 133、oak-storage 74、oak-core 456+12、oak-render 全部、 oak-worker 全部、oak-plugin 208+、oak-app lib 544(含 `OAK_STRICT_PLAYBACK=1` 一次)、oak-timeline 全部。 - 全 workspace 终验(2026-09-22):**104 个测试目标、3179 passed / 0 failed / 7 ignored**(ignored 为既有 GPU 门控)。 - 覆盖率(插桩终测,干净对象集同口径):区域 93.96%、函数 89.59%、行 **93.49%**(180742/193331)、分支 **71.58%**(11805/16491)。分支较修复前 微降 0.37pp——本批刻意移除了若干"容忍型/同义反复"的执行路径(§3.3 交付即 失败、M3 夹具更换、M8 去重),属测试质量的预期代价。 ## 10. 第二轮全量审查(2026-09-22) > 触发:§9 修复完成后,用户要求全量复审。范围:全部未提交改动 > (66 文件,+38731/−281),含第七批修复自身。方法:五个深查子代理 > 分区逐行通读(oak-app 面板群 19 文件、real.rs/renderops、 > oak-render/oak-worker 269 个测试、oak-plugin/oak-codec 约 250 个测试、 > oak-task/core/timeline/storage),审查会话对全部高危论断与 24 条修复 > 声称的关键链条做了原文实证。标注约定同前([实证]/[子代理])。 ### 10.1 修复声称验证总裁定 **24 条声称:20 条完全属实,4 条部分属实,0 条虚假陈述。** 所有核对到的新断言均为可证伪的真断言。上一轮四个高危全部实质化解: - **§3.1**:语义裁决延后**有据**——`.cache/olive-upstream` 的 `block.cpp:62-79`(C++ setter 只调 `set_length_internal`,时间线位置 由 Track 布局推导)与 `clip.cpp:95-124`(非 reverse 时 media_out 版 不动 media_in、media_in 版 `+= old−new`)经原文核对,支持"不是简单 对调、需逐命令裁决"的结论;§8 原局限(未核对 C++ 源码)解除。准备 项落地:`RippleInfo::new` 被 2 个真实测试使用(resize 往返断言 `[-10,100)`+`media_in==-10`、append_gap 断言块数 1→2+Gap 类型, ripple 主体确认可达);KNOWN-SWAP 标注 6 处;`clip_media_in` 断言 1→11 处。[实证] - **§3.2**:`worker_pool_environment_error` 分流精确(`Error::Failed` + `"render worker pool"` 前缀,全仓库仅池创建/启动两处产生该前缀, 产品错误消息穷举核对均不匹配);`DispatcherEnvGuard` RAII + 断言前 显式 restore;两腿断言 `formats == [F32]`。**"永不失败"测试已消灭。** 固有残留:worker 存在但握手/协议回归导致 `start()` 失败仍归环境跳过 (有打印)。[实证+子代理] - **§3.3**:三验收测试统一"历史零交付才可跳过"(`filled/delivered` 取历史最大值,一旦有交付跳过分支永久不可达;source-window 旧缺陷已 修);"交付但未服务"走有界 `assert!(pumps < FAIL_PUMPS)` 失败并携 `serve_misses` 诊断;`OAK_STRICT_PLAYBACK=1` 严格模式 + 设计正确的 `#[should_panic]` 自测;`test_worker_bin()` 解析链(env 存在性过滤→ current_exe 同级→target 兜底,`None` 时不动 env)修掉了硬编码复合 隐患;早期 playhead 断言修复与生产 prune 语义精确匹配。**残留: ci.yml/cd.yml 均未设置 `OAK_STRICT_PLAYBACK`**——门禁 job 上零交付 仍为绿色跳过(可辩护的权衡:全量并行下池饥饿本征 flaky,且兄弟测试 对管理器启动失败一律硬失败、worker 全坏会在别处红;但应在文档显式 登记该取舍)。[实证+子代理] - **§3.4**:ci.yml 增 `icc-profiles-free`(注释精确指向黑屏守卫)+ `system_icc()` 补 `/usr/share/color/icc/sRGB.icc`(该包实际落点) [实证];`gpu_context_for_import` 经 `require_gpu_adapter()` 在 `OAK_REQUIRE_GPU=1` 下硬失败,footage_import 三处跳过均带 `SKIP:`, 头注如实登记 lavapipe 恒跳过与真机验收出处 [子代理,头注已实证]。 残留(低):color.rs(15)/eval.rs(4)/procpool.rs(2) 的旧式 `skipping` 打印未统一为 `SKIP:` 标记(CI 上因 ICC/OCIO/二进制修复均不再触发)。 - **M1–M10 与低危批**:M1(文档改为事实 + 真注册表查询断言)、M2 (Recorder formats + 强制 U8 可证伪测试)、M3(Opacity=0 夹具,双分支 断言互斥)、M4(sqlite 落盘 + load_project 读回 uuid/label)、M5、 M7(0.08 对齐先例,实测值打印)、M8(history.rs 真撤销栈三维断言; instance.rs 5 个 trace 调用全断言且分支敏感;worker.rs 渲染器不变量 +`has_renderer` 一致性+EnvGuard+并发存活)、M9(StagingDecodeGuard 恢复外部预设)全部属实。[实证+子代理] - **部分属实 4 条**: 1. **M6**:otio_backend_test 全齐(轨道/块/footage/转场 3/8 居中 偏移,算术核对正确);loadotio_test 补了轨道/块/footage 但无转场 断言(夹具本就无转场)——声称"两处"只兑现一处。 2. **M10**:external.rs 顶部文档如实列明未单测平台体;4 测试中 3 个 完全真实(Vulkan/IOSurface 格式映射、DMA-BUF 参数校验精确变体); **"D2 别名视图回归"守卫不可证伪**——只对三种别名 `.expect()` 视图 创建成功,而删掉生产修复行(external.rs:607 `dimension: Some(D2)`) 后 `create_view` 照样成功(派生 D2Array 合法),真正的回归(planar pass 的 D2 layout 校验拒绝 bind group)只在**创建 bind group** 时 显现,测试未建 bind group。[实证] 3. **M8-worker 残留**:渲染器两测试仍是 Ok|Err 双向接受(错误串前缀 对即过),未按 `OAK_REQUIRE_GPU` 分流成确定断言——CI(lavapipe)上 "渲染器创建失败"回归不可检出。比 §3.4 已实现的硬失败策略弱一档。 4. **§3.3-CI 接线**:见上。 - 追加修复核实:`source_monitor` 早期 playhead(属实,与生产 prune 语义逐值核对);`preferences_general_tab` 点击→按键竞态(属实,补 `run_until_parked`+整帧 draw+再 park 的同步节拍,断言保持严格 `==128` 无容差,非弱化;配置键 RAII Restore)。[实证+子代理] - dialogs 184 期望值再确认:gpui_widgets `SliderModel` 吸附实现为 `((raw−min)/step).round()`(半值远离零)→ (180−120)/8=7.5→8→184, 与控件既有测试固化的契约自洽。[子代理,公式已核对] ### 10.2 全量深查新发现(第一轮未覆盖区域) **高(1 项)** | 位置 | 问题 | |---|---| | `panels/inspector.rs:564-568` | **恒真断言**:`assert!(debug_bounds(..).is_none() \|\| ..is_some())` 逻辑上永不失败;该测试设置 `pending_add=Some(0)` 并 draw 后本应断言 add 菜单 `.is_some()`。全工作区唯一一处恒真断言。[实证] | **中(12 项)** | 位置 | 问题 | |---|---| | `oak-render/cache.rs:999-1023` | mtime 守卫测试同义反复:`validate` 先污染内存使文件与内存恒同构,`load_state` no-op/守卫反转/真跳过三种实现均通过;名义两个行为均不可证伪。修法:两次 load 间 invalidate 内存范围或用干净实例。[实证] | | `pipeline.rs:959` ↔ `eval.rs:5636` | 进程级 working-space 竞态:pipeline 10 个测试 `pin_legacy_working_space` 不取 eval 的模块私有 `WORKING_SPACE_TEST_LOCK`,同一 lib 测试二进制并行——`footage_working_lut` 的 `is_some()` 有真实 flake 窗口。修法:锁提为 crate 级。[实证] | | `eval.rs:1371-1390`(生产) | **M5 planar-resolve 失败→staging 回退分支零覆盖**,且现有测试缝(`decoded_frames` 全局缓存 + `planar_texture()` helper)本可单元级注入;留档"单机走不到"对该分支不成立。M5 最重要容错路径之一。[子代理] | | `oak-app/mock.rs` ↔ `ofx_params.rs:4886/4825` | MockEngine 未实现 `set_effect_param`/`effect_push_button` 的记录与失败注入(计划 M3.4 缺口)→ 两个"路由/点击触发"名义测试不可证伪;生产侧 `let _ =` 丢弃 Err 加剧不可观测。[子代理] | | `controls.rs:1842-1856`(及 1424-1434) | checkbox 键盘测试不订阅 `CheckBoxEvent::Toggled`,只断"状态不变"——space/enter 处理整体失效不可检出(同仓库 ofx_params.rs:2489 有正确示范)。[子代理] | | `displaycolor.rs:558-578` | 缓存/generation 测试用恒真 `>=` 断言,"同 key 命中不重建/换 key 重建"语义均未验证;:594-599 五个指纹调用零断言。[子代理] | | `oakui/gpu.rs` | **全文件零测试**(M5 功能文件):`upload_rgba16f` 参数校验分支(触碰 GPU 前返回)与 `build_display_lut` 纯 CPU 色彩数学均可确定性测试而未测。[子代理] | | `project_explorer.rs:677-733` | RealEngine 菜单/打开/导入段:注释声称四种效果,整段零断言(同文件 mock 版对相同行为逐一断言,证明可断)。[子代理] | | `real.rs:14789` + `:16234` | 代理 drain `matches!(Ready\|Failed)` 双向接受**原样保留**(§9 未声称处理),叠加弱断言后两文件内**无任何测试断言真实转码产出 Ready**——代理生成 happy path 无守卫。[子代理] | | `real.rs:16147-16155` | "注释声称-结果丢弃"假断言:声称"删除后 name/path 查找 miss",两个查询结果 `let _ =` 丢弃。[子代理] | | `renderops.rs:3749` | `ensure_render_manager()` 失败→SKIP+return;同情形 real.rs 一律 panic(10 处)——同仓库双标,管理器 init 回归可被静默跳过。[子代理] | | `undocommands_test.rs:647-648` | KNOWN-SWAP 漏网:注释仍把互换行为写成规范("Trim-out is out-anchored: the clip's in shifts to 25"),与 common.rs:39 及 §9 C++ 裁决表直接矛盾。另 :874/:907、:659-687 三处固化无标注;:820 slide 标注措辞("grow into each other")与断言(next 缩短)不符。[实证] | **中低/低(择要)** - `hwdecode.rs:331` 全局 `CREATE_ATTEMPTS` 计数器断言未取 `lock_tests` ——并发的 ffmpeg 真实媒体测试会递增它,唯一可能产生 CI 间歇红的 竞态(VDPAU 选型已封死污染面,仅剩自身受竞态)。[实证+子代理] - `decoder.rs:899`/`encoder.rs:362` 注册表注入还原非 panic 安全 (`registry_guard()` 只是锁、Drop 不还原;断言 panic 则 stub 注册表 残留进程,后续测试经 poison 恢复静默用假解码器)。[实证] - `node_factory.rs:2206` 只测自建 mock 入口的边界分支(零生产代码); `:1672` 读两次全局计数断言相等(近同义反复 + 无锁 flake);`:2350` 无断言尾段;`gl_render.rs:1200` 零断言(注释诚实)。[实证+子代理] - `external.rs:715` DMA-BUF 校验测试自建软跳过不受 `OAK_REQUIRE_GPU` 约束(Linux CI 是 Vulkan,不触发)。 - `backend.rs:2886` `user_config_env_override` 非 RAII(M9 同类未修到 此处);`:3579` `OAK_REQUIRE_GPU` 翻转窗口与 16 个 GPU 测试竞态(仅 无 GPU 主机);`:2951` shared-slot 测试锁纪律不一致(潜在)。 - `color.rs:1164/1332` if-let 包裹全部断言的静默逃逸(CI 有真 OCIO, 应硬断言);OCIO 缺失跳过仍静默(无 eprintln);`:1420` 不持 config_lock 且恢复非 RAII。 - 裸 `is_err()` 无消息断言(系统性偏弱,非个别假测试):graphops 23 个错误矩阵(分支隔离夹具 + 精确成功腿维持可失败性)、real.rs 无工程 守卫约 35 处(同文件 :11490 有正确示范)、encodingparams 11 个非法 XML(生产明确区分两种失败原因而未断)。 - "结果丢弃/弱断言"群:source_viewer.rs:375-454(config 动作前后读取 全丢弃、transport 9 个只断 handled)、program_viewer.rs:843(workarea 三事件未断)、timeline.rs:2410(约 20 个命令只断 handled 布尔)、 app.rs:8786(`exit_action_quits` 零断言)、eval.rs:5467/5557(无断言) /6087(OAK_PERF 名义不符)/5585("and_clears" 半截)、procpool.rs :4752/:4764(smoke/半验注入)、worker.rs:2179(frame_failed 不断错误 文本,同族 :2339 证明可断)、nodeops.rs:1332(零断言,名称诚实)、 writethrough_test.rs:96/277(§5 指出未修,未声称)、precache "窗口" 半边仅 liveness 间接兑现。 - env 非 RAII 残留(与已修 M9 同款):ofx.rs:926 `MARKER_ENV`、 program_viewer.rs:964 `HOME`、eval.rs:6095 `OAK_PERF`、 renderops.rs:2881 配置开关、worker.rs:1992 颜色设置。 - 卫生:`crates/oak-task/tarpaulin-report.html` 覆盖率工件混入源码树 (内嵌他机绝对路径,不应提交);计划文档"nodeops 32 个"实为 24 个、 node_factory/render_driver 的批次计数为组合计(文档口径应注明)。 - `ofx_host.rs:68-77` 生产 `emit` 的 `cfg!(test)` 早退:为测试改形的 轻微实例(shipping 行为不变,集成测试真管道补偿),记录在案。 ### 10.3 正面确认(防误伤) - **无成建制造假**:约 500+ 个新测试中,纯假(恒真/零断言/零生产代码) 共 6 个,均有诚实注释或属笔误级;无 `#[ignore]`、无理由 sleep(全部 有界轮询+deadline+超时 panic);故障注入类全部真注入且断言注入生效 (真 SIGSEGV+marker、/bin/false OFX host→紫帧、假 nvidia-smi 六形态)。 - **修复未引入弱化**:preferences 竞态修复是补同步节拍而非放宽容差; render_threads 逐字节断言原样;分支覆盖 −0.37pp 是移除容忍路径的 如实代价且已留档解释。 - 教科书级真测试代表(各区各选):node_editor.rs:844(绕过面板证明 守卫在产品代码)、procpool.rs:4780(PATH 注入六形态+精确换算)、 worker.rs:1757(跨进程 shm 游标环游+0xAB 传播)、eval.rs:4415(GPU 旋转单像素精确+全帧 lit==1)、clip.rs:600(f16 −0 位级保留)、 encodingparams.rs:1096(C ABI offset_of 18 项冻结锁)、app.rs:6610 ("全分支"名副其实)、dialogs.rs:6483(按键改派+磁盘内容往返)、 ofx.rs:920(真插件 marker 参数串+生命周期顺序)、history.rs:325 (真引擎撤销栈三维断言)。 ### 10.4 最终判定与建议 **判定:修复批次诚信且实质有效;工作区达到可提交状态,但下列 8 项 建议先修(均为小改动):** 1. `inspector.rs:564` 恒真断言改 `.is_some()`(一行)。 2. `undocommands_test.rs:647` 补 KNOWN-SWAP 标注(并顺手修 :820 措辞、 补 :874/:907、:659-687 三处)。 3. `cache.rs:999` mtime 测试改为可证伪构造。 4. pipeline/eval 的 working-space 锁提为 crate 级共享。 5. `external.rs:744` D2 守卫补 bind group 创建(或改名去掉"回归守卫" 声称)。 6. `real.rs:14789` 代理 drain:至少在转码可用的环境断言 Ready(可按 ffmpeg 可用性分流,不可用才容忍 Failed)。 7. `renderops.rs:3749` SKIP 改 panic(与 real.rs 对齐)。 8. 删除 `crates/oak-task/tarpaulin-report.html`。 **登记事项(不阻塞提交)**:`OAK_STRICT_PLAYBACK` 的 CI 接线取舍; `hwdecode.rs:331` 补 `lock_tests`(CI 间歇红风险);decoder/encoder 注册表还原改 RAII;M5 planar 回退分支注入测试;gpu.rs 纯 CPU 分支 补测;MockEngine `set_effect_param` 族记录缺口;旧式 `skipping` 打印 统一 `SKIP:` 标记;block.rs setter 语义裁决独立 PR(§9 清单)。 **提交拆分(重申 §2 末建议)**:M5 功能(gpuinterop/external/Planar/ hwdecode 顺序/RefFrame)与覆盖率批次(测试+两处 bug 修复+文档)分开 提交;tarpaulin 工件与本报告/计划文档更新可并入文档提交。 ### 10.5 §10.2/§10.4 处理记录(2026-09-22) **"建议先修 8 项":全部完成。** 1. ✅ `inspector.rs` 恒真断言 → 以具有 debug selector 的分组头断言菜单 已渲染,并断言 `pending_add == Some(0)` 生效。 2. ✅ `undocommands_test.rs` KNOWN-SWAP 标注补齐::647 措辞改为与 `common.rs:39`/§9 裁决表一致,:659-687、:874、:907 补标,slide 处 措辞修正(next 缩短)。 3. ✅ `cache.rs` mtime 守卫测试改为可证伪构造(干净实例装载 + 内存/文件 不再恒同构),守卫反转或真跳过都会失败。 4. ✅ working-space 锁提升为 crate 级 `eval::working_space_test_lock`, pipeline 与 eval 两侧共同持锁。 5. ✅ `external.rs` D2 守卫补 bind group 创建(临时删修复行可复现失败, 已还原)。 6. ✅ `real.rs` 代理 drain 按 ffmpeg 可达性分流:可达硬断言 `Ready` + `ProxyBadge::Ready`;不可达打印 `SKIP:` 并容忍 `Failed`(两种环境均 实测)。 7. ✅ `renderops` 的 `ensure_render_manager` 失败测试改为硬断言(仅 "管理器已初始化" 保留自保护跳过)。 8. ✅ 删除 `crates/oak-task/tarpaulin-report.html`(及其绝对路径泄漏)。 **中危 12 项:** - ✅ MockEngine 记录 `set_effect_param`/`effect_push_button` 调用(含 失败注入开关),`ofx_params` 生产侧改错误日志;两个名义测试改为完整 路由矩阵 + 类型转换值断言(曲线 JSON 先 `set_points` 再发事件)。 - ✅ `controls.rs` checkbox 键盘测试订阅 `CheckBoxEvent::Toggled` 并断言 事件序列;space/enter 处理整体失效会失败。 - ✅ `displaycolor.rs` generation/链缓存改为精确断言(同 key 不重建、 换 key 恰好 +1、指针同一/不同),5 个指纹逐一断言。 - ✅ `oakui/gpu.rs` 补 4 个测试:`upload_rgba16f` 参数校验、f16 打包 (钳制/字节序/256 对齐行距)、display LUT 网格完整性与确定性、key 跟随色彩设置。 - ✅ `project_explorer.rs` RealEngine 段补断言(序列切换、导入计数、 菜单选择与开关状态、引擎分支前置条件)。 - ✅ `real.rs` 两处丢弃的 name/path 查询改为断言;删除后 rename no-op 一并断言。 - ✅ `hwdecode.rs:331` 取 `lock_tests`;decoder/encoder 注册表注入改 RAII `RegistryGuard`(panic 不再泄漏假解码器)。 - ✅ `color.rs` if-let 逃逸改硬断言(OCIO 缺失才打印跳过);配置锁 RAII。`backend.rs` env 覆盖 RAII、共享上下文测试锁纪律统一、 `OAK_REQUIRE_GPU` 竞态窗口消除。 - ✅ env 残留 RAII:`ofx.rs` MARKER_ENV、`program_viewer.rs` HOME、 `eval.rs` OAK_PERF、`worker.rs` 颜色设置、`renderops.rs` 配置开关。 - ✅ 计划文档计数修正(nodeops 32 → 24,组合批次注明口径)。 **登记(不阻塞提交,遗留项)**:`eval.rs` M5 planar 回退分支注入测试 (需要专用测试缝);`node_factory.rs` 三处弱断言与 `gl_render.rs` 零断言; 旧式 `skipping` 打印统一 `SKIP:`;`OAK_STRICT_PLAYBACK` 的 CI 接线取舍; `block.rs` setter 语义裁决独立 PR(§9 清单)。 **验收(2026-09-22)**:全 workspace **104 个测试目标、3185 passed / 0 failed / 7 ignored**(ignored 为既有 GPU 门控)。本批生产改动仅 `MockEngine` 记录字段与 `ofx_params` 错误日志两处可观测性增强。