已接受(2026-09-09 用户逐项授权;v0.20.7 批 2a/2b 交付)
2026-09-09
ADR-013 决策 2(播放暂停驱动 = 复用 A1 共享暂停标志;手动暂停全冻结 vs 自动暂停轻量轮询)落地后,用户实测暴露三类问题:
- 暂停延迟:
pause只置共享布尔,live:paused事件与引擎 reset 全在主循环 500ms 轮询边沿执行,边沿 flush 内同步跑 SenseVoice 整句重打分(有界 3s/句)——点击后 UI 数百 ms~3s+ 才翻转; - 快速恢复丢内容:暂停-恢复落入轮询间隙时边沿不可见(引擎不 reset、无事件记录);恢复侧无 flush/边界处理,
pending_merge链式合并无暂停边界判断,会跨暂停错误合并——半句切碎/尾音丢失; - UI 状态回退:媒体自动暂停(worker 直写标志 +
live:media-paused)与手动暂停(主循环live:paused/resumed)双轨并存、无来源区分;前端课堂页/浮窗/徽标各自维护状态且挂载拉取曾忽略paused字段——事件丢失/重挂后 UI 显示空闲。
另有用户新需求:被采集目标窗口离开前台时自动暂停、回前台自动恢复(区别于仅键盘失焦;熵减自身窗口与软件内切页不触发)。
- 暂停状态升级为带来源的单状态机(
pause_state.rs):PauseSource = Manual | Media | Foreground;manual 为锁存层(持锁期间 auto 提议只记条件不动作,手动解除瞬间重评估 auto 条件),auto 层各条件互不解除、只解自己;PauseShared{paused, total_paused_ms, seq, edge 槽, reason},request API 单写入点;total_paused_ms写纪律不变(仅捕获线程补偿时长)。 - 暂停边沿语义修订(取代 ADR-013 决策 2 中"边沿 flush 尾句 + 引擎 reset 共用停止路径 flush"的重打分行为):暂停边沿用
flush_no_rescore()(跳过 SenseVoice,质量由恢复侧去重与边界保护兜底;停止路径保留重打分);恢复边沿 flush + 去重边界保护 + 按暂停边界切断链式合并状态。 - 漏边沿代数补偿:
seq每完成一个物理暂停区间 +1;主循环按 seq 跳跃检测漏边沿,plan_edge_observation纯函数判定(own_pending 吸收已可见暂停的完成增量),补偿 = no-rescore flush + reset + 合成 Pause/Resume 事件对(时刻取 edge 槽实测冻结点、恢复时刻 clamp 保 DB 单调),每次观察至多一对——消除"引擎不 reset、事件无记录"的全部路径。 - 前台自动暂停(
foreground_pause.rs):启用门 = 窗口锚定(hwnd.is_some(),全屏/纯音频档案停摆);ForegroundGate滞回(250ms 节拍 ×2 拍确认,fa1647aa SUSPECT 先例);自窗中性——经GetAncestor(GA_ROOT)进程比对排除主窗/浮窗/overlay/对话框,防"一点浮窗即误暂停";触发/解除均走 request(Foreground)。 - 契约 reason 化:
live:paused/resumed载荷{"reason": kebab};DB pause/resume payload{"source"};LiveSessionStatus.paused_reason;live:media-paused/resumed保留但前端零订阅(清理候选)。 - 前端每窗口单一数据源:
CaptureStatusProvider(挂载查询含 paused_reason + 事件 + 5s 看门狗 + 守卫错误自愈),课堂页/浮窗/徽标/右栏收口到同一实例(浮窗为独立 webview,各窗一实例),删除全部二级监听与本地双状态。
- 方案 A(选定):来源状态机 + seq 补偿 + 前端单一数据源。优点:手动/自动语义机器化(根治 fa1647aa 类多写者漂移)、丢内容路径结构性消除、UI 不再依赖单点事件。代价:REQ-291 媒体暂停相关直写点全部收敛(frame worker 语义面改动,需真机走查)。
- 方案 B:确认式跨线程回执(命令等捕获端点 Stop 回执再返回)。否决理由:命令置位 µs 级、端点停采 10ms 级,UI 无可感知收益;需跨线程回执通道与超时降级,复杂度不成比例。
- 方案 C:仅补丁(暂停边沿跳过重打分 + 挂载补读 paused 字段)。否决理由:轮询间隙漏边沿、链式合并跨暂停、多窗状态分裂等结构性缺陷未除——不符合"优先彻底方案"的用户原则。
- 暂停是采集正确性的核心语义:延迟、丢内容、状态回退三条线共享同一根因(无来源布尔 + 轮询边沿 + 重打分阻塞 + 前端多写者),单点收敛收益最大;
- 自动暂停(前台)与既有媒体随播随停共用同一状态机底座,未来任何新自动源(静音/失焦/可见性门控)只加一个条件源,不再触碰驱动端;
- 前端单一数据源顺带修复"刷新后徽标空白"旧债,且为后续更多窗口(如后续收件箱/复习域页)提供同一模式先例。
- 暂停生效确定性:点击后 UI 在 ≤1 个主循环节拍 + 无重打分(数十 ms~500ms)内翻转;
- 快速暂停-恢复不再丢段/碎句/漏事件;DB 事件成对且时刻单调;
- 徽标/浮窗/课堂卡 reason 三态文案,自动暂停原因可见;
- 前台切走自动停、切回自动续(窗口锚定采集),手动暂停期间自动条件不越权。
- REQ-291 媒体暂停链路面改动:auto_paused 局部标记删除、全部直写点收敛 request(Media),需真机样例走查(手动恢复后视频仍暂停→重锁存链路);
- 事件载荷变化:旧前端监听忽略载荷即安全;旧后端(无此版本)对旧前端发空载荷 → UI 回落"已暂停"不崩;
- 前台判定真机标定项:alt-tab 快速往返、全屏游戏抢前台、置顶弹窗;双屏并排场景(目标可见但前台在另一屏)会暂停——可见性门控留作可选项待用户裁决。
- 浮窗 always-on-top 点击被误判前台切换(最高风险)——自窗中性已覆盖,仍需真机验证;
- media 恢复语义变更回归——fa1647aa 修复链路(800-807 兜底重锁存)已机器化并保留 worker 侧兜底;
- 无窗口锚定采集的前台规则停摆属设计口径(用户已确认),不得静默启用。
cargo test --test app_lib_tests:2287 通过 / 0 失败 / 6 ignored(全量,隔离运行);- 前端:全量 vitest 597/597、
tsc --noEmit0 错误; - 新增核心文件实测(2026-09-09 审查纠偏,原 ≤300 口径失真):pause_state.rs 336 / live_session_pause.rs 353(审查修复轮 1 后)/ foreground_pause.rs 227——前两者超 300 已按 300-600 档登记 line-limit-exemptions.md;
- 真机验收清单 8 条登记于 v0.20.7 交付记录(前台阈值标定待真机)。
- ADR-007(live-session 生命周期)、ADR-013(引擎预热与播放暂停驱动——本 ADR 修订其决策 2 的边沿 flush 语义与同标志/同事件表述)、ADR-030(ASR 质量批,flush/重打分参数化先例)
- 需求:REQ-308/309/310(requirements-pool,2026-09-09 备注)
- 设计:docs/archive/2026-09-09/2026-09-09-capture-pause-autopause-design.md([ ] 已归档 2026-09-09)