Start each repeat after its own manifest entry, refuse packets from a restarted or stopped camera, keep a simulated repeat from reading as recorded evidence, and decide completeness from the writer report. Add the operator summary (four files plus an atomic pointer) and read-only video review of a hold window. Verified with the full Autocal suite (567 passed), the shared recorder/playback files (57 passed), the lint gate and the documentation gate; the two pre-existing panel_check layout failures also fail on a clean HEAD worktree.
11 KiB
DeepSeek 子代理执行清单
状态:2026-10-17 已实施,仅软件验证,待实机验收。本清单与主计划、数据契约配套;下面的复选框记录实际完成情况,末尾是本次真实执行结果。
主代理指令
先读工作区及作用域 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 文件的最终合并权。并行任务对同一文件的修改必须串行交接,不能各自覆盖。建议最多三个实现子代理;先完成依赖再分派,不让代理空等或自行更改契约。
执行波次
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:一名只读验收代理独立复核(562 项实跑 exit 0);提出 3 项 major、9 项 minor,主代理已修 3 项 major 与 6 项 minor,其余记为未接线或已接受。
首个检查点在 A2/B2/C1 后:身份、收尾、公式全部通过才接界面。最终检查点:新进程打开两种会话,选择已确认窗口播放,打开报告及两 CSV,中止/缺视频能解释原因。任何必需环境缺失或测试跳过都列为未验证。
验证命令与本次结果
以下命令已在 app 根执行;未运行真实设备。
$pythonExe = 'D:\orisys_ws\orisys-app\.venv-build\Scripts\python.exe'
& $pythonExe --version
& $pythonExe -m pytest apps/autocal/tests -p no:cacheprovider --basetemp=.scratch/autocal-recording-summary/pytest-full
& $pythonExe -m pytest shared/tests/test_experiment_recorder.py shared/tests/test_record_lifecycle.py shared/tests/test_record_semantics.py shared/tests/test_playback.py -p no:cacheprovider --basetemp=.scratch/autocal-recording-summary/pytest-shared
& $pythonExe tools/lint_gate.py
& $pythonExe apps/autocal/tools/panel_check.py
& $pythonExe D:\orisys_ws\scripts\doc_lint.py
| 项目 | 结果 |
|---|---|
| T0 | frames_index.py(帧/力身份关联、重复帧排除、采集目录解析)、tests/evidence_helpers.py(真实可解码 MP4、两种会话样例、可重启来源的假 worker)、test_frames_index.py |
| A | capture_guard.py(CaptureGuard 与 capture_verdict)、multipoint.py 显式 repeat 归属/收尾状态机/来源重启判定、trial.py 复用同一判定、界面录像状态与"未就绪不能确认"、两份 locale |
| B | summary.py(窗口表、逐轴前向 OLS、端点/初始阶跃、旧 stable_means.csv 兼容行)、summary_export.py(四件文件、原子指针、输入哈希复核、取消/倒退保护) |
| C | video_review.py(按身份定位与解码、分段切换、释放 decoder)、ui/video_review_dialog.py,记录总览与保持复核对话框的录像入口 |
| D | 采集终态与复核保存触发发布;失败可重试且不改采集结果;两份格式说明与三份计划状态已同步 |
| Autocal 全量 | 562 项,0 失败、0 跳过,62.0 s;junit 证据在 .scratch/autocal-recording-summary/final-autocal.xml |
| shared 回归 | 4 个文件全部通过(recorder、lifecycle、semantics、playback) |
tools/lint_gate.py |
status: clean,仅 1 条已解释的 BLE001 抑制提示 |
apps/autocal/tools/panel_check.py |
260 项中 2 项失败:finger 页 QDoubleSpinBox 高度大于父容器。用 HEAD 的独立 worktree 复跑同样失败,属先前存在,不是本次改动引入 |
scripts/doc_lint.py |
本次涉及文档均在 reference 上限 3000 内,门禁通过 |
| D2 独立验收 | 只读评审提出 3 项 major(来源停止仍判完整、模拟写成完整、收尾期可开新场)与 9 项 minor;3 项 major 与 6 项 minor 已修并加回归测试,2 项记为已接受(首帧解码探测在收尾轮询内、有界)与未接线(发布取消只有库级参数,无界面按钮) | | 回归数量 | 新增 est_frames_index、 est_multipoint_recording、 est_summary、 est_summary_fit、 est_summary_export、 est_summary_lifecycle、 est_video_review、 est_video_review_dialog |
未验证:真实相机与控制器、24 小时分段的解码耗时、D:\orisys_ws\data\dd02-gl 的现场私有数据路径(只核对行数,不作为夹具)、D2 独立人工验收。旧独立 stable_means.csv 目前只有 summary.legacy_window_rows() 映射与测试,尚未接入界面导入;会话内旧记录可读,缺视频时按原因排除。若以后改 shared,另跑实际受影响的 Studio 读取/记录测试,不以 Autocal 测试替代消费者回归。