From d7540f52ec309d4d202fe4f91ecb55d65c28d2d1 Mon Sep 17 00:00:00 2001 From: ykcheungab Date: Sat, 17 Oct 2026 09:49:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=B6=E5=AE=9A=20Autocal=20=E5=BD=95?= =?UTF-8?q?=E5=83=8F=E5=A4=8D=E6=A0=B8=E4=B8=8E=E6=B1=87=E6=80=BB=E5=AE=9E?= =?UTF-8?q?=E6=96=BD=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docs/recording-summary-contract.zh.md | 95 +++++++++++++++++++ .../autocal/docs/recording-summary-plan.zh.md | 79 +++++++++++++++ .../docs/recording-summary-tasks.zh.md | 92 ++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 apps/autocal/docs/recording-summary-contract.zh.md create mode 100644 apps/autocal/docs/recording-summary-plan.zh.md create mode 100644 apps/autocal/docs/recording-summary-tasks.zh.md diff --git a/apps/autocal/docs/recording-summary-contract.zh.md b/apps/autocal/docs/recording-summary-contract.zh.md new file mode 100644 index 0000000..d6c6ce1 --- /dev/null +++ b/apps/autocal/docs/recording-summary-contract.zh.md @@ -0,0 +1,95 @@ +# 录像和操作员汇总数据契约提案 + +状态:2026-10-16,待实施。属于[实施计划](recording-summary-plan.zh.md);既有采集字段仍以[单次格式](calibration-data-format.zh.md)及[多点格式](multipoint-data-format.zh.md)为准。以下新增字段、接口和文件名均是提案,不能按已实现能力使用。 + +## 文件组织 + +```text +___/ + session.json + stable_means.csv # 多点既有兼容输出 + trials/trial-001/ # 单次格式,保持不变 + session.json + raw_0001.mp4 + frames.csv + forces.csv + reference.csv + events.csv + sites//repeat-001/ # 多点格式,与 trials 二选一 + session.json + reference.csv + events.csv + capture/ + session.json + raw_0001.mp4 + frames.csv + forces.csv + derived/ + review__/ # 既有 review 快照 + review.json + overview.json # 现有流程有生成时保留 + baseline_.png + summary__/ + summary.json + summary.html + baseline_load_data.csv + sensitivity_values.csv + summary-latest.json # 最后成功发布的相对路径指针 +``` + +不建立第二份录像,不改变两种格式的原始目录。新汇总沿用样例文件名,但明确版本化字段;旧 `stable_means.csv` 保留原接口,不将新表悄悄写成旧表。新读取器缺少指针时仍可打开旧会话,绝不通过修改旧 manifest 补造证据。 + +导出先在唯一临时目录写齐并验证,再发布同盘目录,最后原子替换指针。失败保留旧指针,报告导出失败,不回滚采集状态。指针使用相对路径、summary_id 和内容哈希;并发发布由会话级单一任务串行化,取消后的旧任务不能更新指针。原始文件、历史 review 和已发布 summary 均不覆盖。 + +## 录像身份、时间和生命周期 + +逻辑身份使用 `(calibration_session_id, trial_id, capture_session_id, frame_id)`;保持窗口再加 `step_index`。共享 recorder 的整数 session_id 不等于标定 session_id。同试验来源重启不得静默复用 frame_id;中止并新建 trial。重复身份、行数不符或缺关联必须报错/排除,不能退回按行号拼接。 + +帧和力按采集 session、frame_id 关联;帧提供 `t_host_mono_ns`、UTC、time_basis 及 `segment/segment_frame`。仅同一次实时采集的 `host_camera` 可与保持窗口 `[start,end)` 比较。UTC 只追溯;`host_replay` 不提供原实验同步,`host_fallback` 标未验证。相机内丢帧与写盘丢帧分别记录。 + +定位窗口时选择范围内首个已入视频的有效帧;无帧就显示缺失,不跳到窗口外假装有证据。播放与曲线按已保存索引关联,可见时间跳跃;媒体 FPS 只影响容器播放,不用于实验时间换算。关闭/切换 trial 释放 decoder;后台结果以请求代次过滤。 + +```text +idle → starting → recording → closing → complete + └失败──────┴失败/中止───────→ incomplete +``` + +先创建当前 trial 清单,再以显式 trial 引用启动 recorder;禁止用 `trials[-1]` 隐式归属。首个可写入帧及 writer 正常后才允许保持确认。启动失败卸载 sink 并结束 writer;每次 start/stop 清理本会话来源引用,simulation 不继承 live worker。 + +停止时先移除 sink,再异步排空;到终态后校验 report、帧索引和视频可读性,再更新 repeat 和根清单。步骤完成、录像完成分别保存。至少零帧、写入错误、录像/数据丢失、不可解码、来源停止均阻止“证据完整”;相机来源丢帧单列警告,是否影响实验可用性保留待定,不伪造精度阈值。超时保持 closing/incomplete,不复用仍在写入的目录。 + +建议为多点 manifest 增加 `capture_status`、`capture_reason`、`capture_report`;只增加可选字段,读取器缺省为 unknown。不要把旧的 `images.captured=true` 当成录像验证成功。版本升级仅在旧读取器实际不兼容时实施并加兼容测试。 + +## 窗口均值表 + +`baseline_load_data.csv` 每个实际保持尝试一行;重测不可覆盖前次,使用 trial 内 `hold_id` 区分相同 step。关联键为 session_id、trial_id、hold_id;point 标签只用于展示。映射哈希+UV 校验点身份,缺哈希时保留来源命名空间,不按 UV 猜测跨 session 同一点。 + +旧格式的 hold_id 由 reference 文件内数据行序号派生,并与该文件哈希共同固定身份;不回写采集文件。人工裁剪保留 hold_id,只改变选择区间。必须保留原始行号再过滤,不能过滤后重新编号。 + +| 字段组 | 字段与含义 | +|---|---| +| 来源 | `schema_version, summary_id, session_id, trial_id, hold_id, site_id, point, repeat_index, step_index, source_file`;路径相对会话根 | +| 位置 | `U,V,mapping_sha256`;缺位置为空,不补零 | +| 载荷 | `reference_source,branch,target_load_n,reference_load_n`;实际参考和目标分开,baseline 标准化为 zero | +| 时间 | `t_start_host_mono_ns,t_end_host_mono_ns,time_basis,window_method,stability_verified` | +| 样本 | `samples_total,samples_valid,samples_excluded` 及每轴实际参与统计数;单独统计无效、未关联及无视频帧 | +| 结果 | `FN_mean,FX_mean,FY_mean,FN_std,FX_std,FY_std,unit`;raw 与 N 不混合 | +| 状态 | `trial_status,capture_status,review_status,eligible,excluded_reason`;不完整也列出,防止静默遗漏 | + +默认自动输出候选后半保持窗口,`window_method=hold_second_half_v1`,不自动认为稳定。人工确认后使用现有 selections 的精确区间,`window_method=review_selection_v1`。统计默认有限且有效的原始分量,样本标准差 ddof=1;不足两样本为空。新表不默默继承旧表按轴去异常值;若以后支持过滤,须另给版本、参数和每轴计数。 + +候选与已确认数据不混合拟合;同一 trial 的被重测废弃保持段列出原因且排除。正式统计只用完整 trial、可比较时间及明确参考的窗口,缺失数值写空单元格/JSON null。 + +## 灵敏度表与报告 + +`sensitivity_values.csv` 每点每 trial 每轴每种审核集合一行;纵向结构允许缺轴。含身份、`component,review_status,method,slope_raw_per_N,intercept_raw,R2,rmse_raw,endpoint_raw_per_N,initial_step_raw,reference_min_N,reference_max_N,window_count,status,reason`。导出保持双精度,不沿用旧表六位有效数字作为计算输入。 + +方法固定为 `raw_on_reference_ols_v1`:以实际参考 N 为 x,原始窗口均值为 y,在同一 trial 内用初始零载和加载窗口等权拟合 `y=a*x+b`。卸载单独展示,不进入该拟合。至少两个不同参考力,否则 unavailable;不跨 trial 混合不同零点。报告按点汇总合格 trial 斜率的均值、样本标准差和数量,不把它冒充新的联合拟合,不平均 R²。 + +R² 为 `1-SSE/SST`;常量信号 SST=0 时为空并标记 flat_signal,零斜率不反推增益。endpoint 每 trial 用最高加载与初始零载的差除以参考力差;initial_step 为最低正加载均值减初始零载。跨 trial 只汇总这些量的均值及数量,缺配对或分母为零为空;不跨 trial 拼端点。 + +现有 `_fit()` 是 `N=gain*raw+offset`,其 `1/gain` 与上述正向 OLS 不一般等价。旧审核拟合不更名、不覆盖;新表明确方法,FN/FX/FY 对法向输入的响应不称为三轴力标定。高 R² 不代表物理精度或独立验证。 + +`summary.json` 保存版本、源文件 SHA256、review 相对路径/selections 哈希、软件版本、生成 UTC、统计方法、单位、缺失原因和全部表格结果;`formal_conclusion=false`。已复核汇总引用既有 review,不复制一套审核状态;自动候选无需预先创建 review。保存时重验输入哈希,变化则拒绝发布。HTML 只呈现同一份对象,转义操作员输入和路径,无外部网络依赖。 + +报告首屏显示型号/SN、完成与缺失点数、录像完整性、待复核窗口和导出状态;随后是逐点响应、三分量灵敏度、既有重复性/滞后/留一 trial 验证和证据链接。没有独立验证时明确显示不可用。停止或中止也生成失败摘要;复核变化生成新版本,不改原始数据。 diff --git a/apps/autocal/docs/recording-summary-plan.zh.md b/apps/autocal/docs/recording-summary-plan.zh.md new file mode 100644 index 0000000..098e6d5 --- /dev/null +++ b/apps/autocal/docs/recording-summary-plan.zh.md @@ -0,0 +1,79 @@ +# Autocal 录像复核与汇总实施计划 + +状态:2026-10-16,待实施。范围:补齐录像可靠性、按事件回放和操作员汇总;不改变运动控制,不部署标定系数。详细字段见[数据契约提案](recording-summary-contract.zh.md),DeepSeek 执行清单见[任务分工](recording-summary-tasks.zh.md)。本计划补充[原实施计划](implementation-plan.zh.md),不把草稿描述当作功能验收。 + +## 现状与问题 + +调查基线:app `main`、HEAD `2cec3d905b193670e3de5df5f2de6dd4b1e8e3d7`。结论来自源码和样例 CSV,未运行相机、平台或故障复现。工作树已有 `motion/service.py`、`record_diagnostics.py` 和测试计划改动,实施前须重新核对,不能覆盖。 + +| 证据位置(相对应用源码目录) | 已有能力及缺口 | +|---|---| +| `trial.py: ManualTrial.start/finish/poll` | 已接共享录像器,单 trial 连续录像;异步排空及完整性判断已有模式可复用 | +| `multipoint.py: _start_images/_release_images/_close_repeat` | 已录 `capture/raw_*.mp4`,但停止时未采用 recorder report 判断 repeat 完整性 | +| `multipoint.py: _open_repeat/_start_images` | 后续 repeat 在加入清单前启动录像,随后以 `trials[-1]` 写关联,可能更新前一 repeat | +| `multipoint.py: start` | 会话重新开始未清除待连接 worker,存在旧来源跨会话继承风险;需回归证明 | +| `ui/multipoint_panel.py: _poll` | 当前主要处理保持倒计时,缺少与单 trial 等价的来源/录像失败检查 | +| `multipoint.py: stable_component_rows` | 已有 `stable_means.csv`,采用保持后半段、分量去异常值;帧与力按过滤后的行序关联,须改成明确身份校验 | +| `session_review.py`、`record_overview.py` | 已有保持段复核、FN 拟合及质量统计,复用其审核状态;缺少直接的视频复核入口和统一三分量导出 | + +因此首要任务是让现有录像可验证、可发现、可回放,而非再写一套录制器。用户现场的缺录像原因仍待核对实际输出和运行版本;上述静态缺口不能直接证明现场原因。 + +## 参考样例与设计选择 + +`D:/orisys_ws/data/dd02-gl` 包含一个 MP4 和两张 CSV。`baseline_load_data.csv` 有 60 行,15 个 UV 点各有 0/1/2/3 N 四档,均为 repeat 1;`sensitivity_values.csv` 有 15 行。只有 11 个不同 site_id,多个来源重复使用编号,不能按 site_id 单独合并。 + +样例表缺少原始窗口时间、帧索引、配置/映射身份和完整来源文件,不能反推出与该 MP4 的同步关系,也不能证明这些窗口已经人工复核。只借鉴“窗口均值表+逐点灵敏度表”的操作方式,不把历史样例自动升级为已验证标定。 + +方案默认录传感器原始输入画面,不录桌面或第二台外部相机;现有 MP4 有损编码不称为无损原始图像。每 trial/repeat 一条逻辑录像,含零载、换档、加载、卸载和恢复;保持段不另建视频。跨测点间的对准等待不承诺录像。 + +首期保留当前 24 小时分段设置及单 trial 完整性约束,读取端支持已有分段索引。若以后改成短分段,必须同时修改 `ManualTrial.poll()` 的单段限制并验证跨段行为,不能只改录制参数。 + +保留现有两种采集目录和共享格式,新增可重建的汇总目录;不要移动、删除或复制原始视频来追求目录整洁。旧记录按原样读取,缺视频显示“无录像证据”。 + +## 数据流和界面 + +```mermaid +flowchart LR + A[相机与采集时间] --> B[FingerAcquisitionWorker / SdkPacket] + B --> C[有界队列 / ExperimentRecorder] + B --> D[实时预览] + C --> E[视频 / frames / forces] + F[人工参考与保持事件] --> G[reference / events / session] + E --> H[只读身份与完整性检查] + G --> H + H --> I[保持段选择与视频回放] + I --> J[窗口统计与灵敏度] + J --> K[summary.html / 两份 CSV / summary.json] +``` + +采集线程只提交数据,不编码、不生成报告。写盘线程负责录像;Qt 线程管理状态和呈现。回放解码、校验和导出在后台执行,通过现有 `ReviewJob` 或专属解码任务返回结果;旧任务结果不得覆盖用户新选的 trial。 + +采集页展示“未就绪/录制中/收尾中/完整/证据不完整”、实际写入帧数、丢帧、时长和保存位置。开始保持必须等录像就绪;完成按钮进入收尾,不立即报成功。故障通知操作员停止加载并保存未完成证据,不新增自动运动。 + +记录总览继续作为唯一入口。点选测点、repeat、保持段即可播放对应画面,支持播放/暂停、逐帧、定位起止点;同步显示原始力曲线、实际参考力和有效状态。按帧索引定位,不用播放器秒数推算实际采集时间。采集中可见录像状态,回放首期只开放已收尾的 trial,避免同时读取未封口容器。 + +结束整场后自动生成候选汇总;人工复核保存后生成新的已复核汇总。操作员默认只看一个报告及两张表,原始目录通过“查看原始证据”展开。报告区分采集完整性、稳定段确认和计算可用性,不输出未经定义的合格/不合格结论。 + +## 实施与交付顺序 + +1. 先用两个连续 repeat、连续两个 session、live 后 simulation 证明录像归属和生命周期缺口,并锁定新增契约。 +2. 修正现有录像收尾、失败传播和 UI 状态,以合成相机完成两点两次采集闭环。 +3. 并行开发只读回放和汇总计算,再串入同一记录总览;禁止跨应用导入 Studio 私有控制器。 +4. 增加自动汇总、原子发布和旧记录兼容;最后执行软件回归及独立人工复核。 + +粗估为 10–15 个工程人日,最多三名实现子代理并行时约 5–8 个工作日;这是排期估计,不是 DeepSeek 运行时承诺,不含设备等待。主代理负责共享文件、接口冻结和集成。 + +## 验收与停止条件 + +| 场景 | 必须得到的结果 | +|---|---| +| 两点各两次,含中止重试 | 四次正常试验各指向自己的录像;中止另占身份,不覆盖文件 | +| 断流、写盘失败、编码失败、队列溢出 | 不再报采集完整,仍可打开残存数据;界面不因排空阻塞 | +| 点击一个已确认窗口 | 定位其首/末有效帧,曲线、参考和视频使用同一采集时间及 trial 身份 | +| 两种现有格式与历史缺视频记录 | 可读且保留缺失原因;不伪造帧或稳定性 | +| 汇总重算 | 数值可由输入及窗口选择复算,结果不修改原文件;无有效数据保持空值和原因 | +| 操作员交付 | 一个报告链接能找到全部测点、失败原因、两张 CSV 和原始证据 | + +软件完成必须通过任务清单中的测试、文档门禁和无硬件操作演示;相机吞吐、磁盘容量、驱动延迟和视频可解码性另做实机测量。真正加载实验需明确设备、载荷/运动边界和停止条件后执行。 + +本期不做 FT 同步、自动加载、批量跨 session 合并、历史视频补时间、原始数据清理或算法状态精确重演。录像支持视觉复核,不能保证有状态算法从全新进程逐帧复现。 diff --git a/apps/autocal/docs/recording-summary-tasks.zh.md b/apps/autocal/docs/recording-summary-tasks.zh.md new file mode 100644 index 0000000..73c7419 --- /dev/null +++ b/apps/autocal/docs/recording-summary-tasks.zh.md @@ -0,0 +1,92 @@ +# DeepSeek 子代理执行清单 + +状态:2026-10-16,全部待实施。本清单与[主计划](recording-summary-plan.zh.md)、[数据契约](recording-summary-contract.zh.md)一起交给 DeepSeek 主代理。本次仅完成规划,没有启动 DeepSeek 实现;当前工具不提供 DeepSeek 模型。 + +## 主代理指令 + +先读工作区及作用域 AGENTS、工程约束、上述两份计划。重新检查 app 分支、HEAD、index、工作树;保护已有 `motion/service.py`、`record_diagnostics.py`、`docs/test-execution-plan.zh.md` 及根文档改动。只实现录像证据与汇总,不运行真实控制器或加载,不提交或推送。缺少现场复现不能宣称已修复现场原因。 + +每项先读列出的代码、写能区分错误行为的测试,再做最小改动。任务结束交回:文件清单、验证命令和结果、未验证项、接口变化。新测试临时文件统一放 `.scratch/autocal-recording-summary/`;运行期间保留 `.active`,测试使用唯一 basetemp。不得复制依赖仓库代码或另建录像引擎。 + +主代理拥有接口签名、公共测试夹具、`multipoint.py`、`session_review.py` 和两份 locale 文件的最终合并权。并行任务对同一文件的修改必须串行交接,不能各自覆盖。建议最多三个实现子代理;先完成依赖再分派,不让代理空等或自行更改契约。 + +## 执行波次 + +```text +T0 契约与回归夹具 + → A1 录像归属 → A2 异步结束与故障 → A3 采集状态界面 + → B1 身份与窗口统计 → B2 灵敏度 → B3 汇总文件发布 + → C1 帧定位与回放 → C2 记录总览接入 +A3 + B3 + C2 → D1 自动导出和兼容 → D2 独立验收 +``` + +A、B、C 在 T0 后可并行,但 `multipoint.py` 的改动优先归 A;B 先实现独立纯函数,新摘要接入由 D1 串行完成。C1 只用只读夹具,不等待真实录制修复。每个任务建议控制在 2–5 个文件。 + +## T0:冻结可测试接口(主代理,0.5–1 日) + +- [ ] 读 `trial.py`、`multipoint.py`、共享 `record/experiment.py`、`record/playback.py`,确认 report 和帧身份可用字段;冻结输入输出,避免接口臆造。 +- [ ] 建 `tests/evidence_helpers.py`,含双 repeat、两种格式、缺视频、重复 frame_id、断流、重测及非线性样例。可解码视频使用真实小文件,不能仅写假 MP4 字节。 +- [ ] 将 proposed 接口落实为:窗口选择复用现有 review;summary 构建返回普通 dict;export 接收不可变结果;回放定位接收 trial/hold 身份,返回 segment 和帧号。现有公共 recorder 签名保持不变。 + +验证:夹具能同时驱动现有读取器和新增回归;用小型独立数值例子断言预期。缺共享 API 时仅在有两个实际调用者的情况下提取,不导入 Studio 私有代码。 + +## A:录像可靠性子代理(2–3 日) + +交接提示:你负责录制生命周期。先重现后续 repeat 错归属、连续 session 来源残留和 writer 失败仍 complete;不得修改统计算法或 motion。 + +| 任务/文件 | 验收条件 | 验证 | +|---|---|---| +| A1:`multipoint.py`、`test_multipoint.py` | 当前 trial 先登记,显式归属;两次 repeat 路径独立;live 后 simulation 无 sink 或 writer 泄漏 | 两点两 repeat、重新 start、attach 失败、重复 stop 回归 | +| A2:同模块+`test_multipoint_recording.py`;必要时 `trial.py` | poll 驱动 closing,report 后决定完整性;断流、零帧、编码异常、溢出、收尾失败均保留原因,不阻塞 Qt | fake writer 故障注入+真实短视频关闭/重开;source 重启不混 frame 身份 | +| A3:`ui/multipoint_panel.py`、`ui/calibration_panel.py`、`test_calibration_feedback.py` | 待就绪不能确认保持;显示录制/收尾/失败和保存位置,完成后仍可预览;关闭窗口可收尾 | Qt 事件循环在排空期间可响应;重复点击不重复启动 | + +必要文案由主代理统一更新 locale。状态测试必须检查磁盘结果和清单,不能只断言按钮文字。 + +## B:汇总计算子代理(2–3 日) + +交接提示:你负责把已有证据变成两张可追溯表。样例仅作布局与数值核对,不是身份或同步真值。不得把候选窗口自动标为稳定。 + +| 任务/文件 | 验收条件 | 验证 | +|---|---|---| +| B1:新增 `summary.py`、`test_summary.py`;协调 `session_review.py` | 两种格式统一身份关联;保留候选/确认、重测及排除原因;不按行序拼接;raw/N 隔离 | 乱序、缺行、重复 ID、无效值、不同轴缺失、手选窗口、未完成 trial | +| B2:同模块+`test_summary_fit.py` | raw 对实际参考 OLS,三轴分别计算;R²、endpoint、initial_step 的空值规则明确 | 独立手算直线/非线性、常量、重复参考、缺 baseline;证明与逆向拟合取倒数不同 | +| B3:新增 `summary_export.py`、`test_summary_export.py` | 一次发布 HTML/JSON/两 CSV,内容同源;相对路径、输入哈希、历史版本和原子指针 | 写盘失败不污染旧结果;并发/取消不倒退指针;HTML 转义;CSV 精度及中文 | + +dd02-gl 的 60/15 行与重复 site_id 必须记录为历史案例;测试用小型合成样例,不能依赖该机器上的私有数据路径。旧 `stable_means.csv` 兼容层由 D1 接入,不能暗改其过滤方法。 + +## C:视频复核子代理(2–3 日) + +交接提示:你负责让操作员从保持段找到原始画面。复用 shared `RecordingReader`;读取视频不重新计算标定。长录像解码必须在后台,切换 trial 不回显旧任务。 + +| 任务/文件 | 验收条件 | 验证 | +|---|---|---| +| C1:新增 `video_review.py`、`test_video_review.py` | 通过采集时间→帧身份→分段帧定位;无视频/缺帧有原因; decoder 生命周期明确 | 可识别帧编号的小视频、跨段、时间缺口、非均匀采样、无视频窗口;逐帧校验结果 | +| C2:新增 `ui/video_review_dialog.py`,修改 `ui/record_overview_dialog.py`,新增 UI 测试 | 点窗口可播放、暂停、逐帧并显示参考与曲线;只开放已收尾 trial;不阻塞界面 | 旧格式/多点格式、快速切换、关闭时任务仍运行、异常恢复、无硬件人工点击检查 | + +首期不新增 QtMultimedia/FFmpeg 安装依赖,先验证现有 decoder;如部署环境无法可靠定位,给出实测证据及最小替代方案再由主代理决定。 + +## D:集成与独立验收(2–3 日) + +- [ ] D1:主代理修改 `multipoint.py`、`trial.py`、`ui/record_overview_dialog.py` 与 locale,将采集终态触发候选导出、保存 review 触发新汇总串起来;导出失败可重试且不改采集结果。加入 `test_summary_lifecycle.py`。 +- [ ] D1 后同步三份既有格式/实施说明和新契约状态,注册文档;不把计划全文复制到多个位置。 +- [ ] D2:换一名只读验收代理检查完整流程及失败场景,核对原始文件哈希、录像归属、结果数字和旧消费者。主代理处理发现并复跑相关检查。 + +首个检查点在 A2/B2/C1 后:身份、收尾、公式全部通过才接界面。最终检查点:新进程打开两种会话,选择已确认窗口播放,打开报告及两 CSV,中止/缺视频能解释原因。任何必需环境缺失或测试跳过都列为未验证。 + +## 验证命令模板 + +以下命令是实施后的计划,不是本次已执行结果。运行前核对解释器和实际新增测试名;在 app 根执行,主代理选择本波次测试文件。现有 `conftest.py` 使用旧 outputs 临时目录,T0 须将本任务测试夹具定向 scratch,避免测试运行污染真实偏好或输出。 + +```powershell +$pythonExe = 'D:\orisys_ws\orisys-app\.venv-build\Scripts\python.exe' +& $pythonExe --version +& $pythonExe -m pytest apps/autocal/tests/test_multipoint.py apps/autocal/tests/test_multipoint_recording.py apps/autocal/tests/test_manual_trial.py -p no:cacheprovider --basetemp=.scratch/autocal-recording-summary/pytest-a1 +& $pythonExe -m pytest apps/autocal/tests/test_summary.py apps/autocal/tests/test_summary_fit.py apps/autocal/tests/test_summary_export.py apps/autocal/tests/test_summary_lifecycle.py -p no:cacheprovider --basetemp=.scratch/autocal-recording-summary/pytest-b1 +& $pythonExe -m pytest apps/autocal/tests/test_video_review.py apps/autocal/tests/test_session_review.py apps/autocal/tests/test_session_review_multipoint.py apps/autocal/tests/test_record_overview.py -p no:cacheprovider --basetemp=.scratch/autocal-recording-summary/pytest-c1 +& $pythonExe -m pytest shared/tests/test_experiment_recorder.py shared/tests/test_record_lifecycle.py shared/tests/test_record_semantics.py -p no:cacheprovider --basetemp=.scratch/autocal-recording-summary/pytest-shared1 +& $pythonExe tools/lint_gate.py +& $pythonExe apps/autocal/tools/panel_check.py +& $pythonExe D:\orisys_ws\scripts\doc_lint.py +``` + +若修改 shared,另跑实际受影响的 Studio 读取/记录测试;不以 Autocal 测试替代消费者回归。最终记录真实命令、收集数、通过/跳过数和手工操作证据。真实设备试验单独排期,离线全绿不算硬件验收。