# 2026-06-14 X-ASR 尾字修复 ## 用户目标 用户确认按“X-ASR 松键后尾部采集保护”方案修复偶发尾字掉字问题,并要求: - 修完后必须拉两个代码审核员审核改动。 - 必须拉 QA 做回归测试。 ## 改动范围 仅改 X-ASR 实验分支的尾部采集相关代码与测试: - `privatevoice.src/internal/engine/engine.go` - 新增 `ReleaseTailCaptureEngine` 可选能力接口。 - `privatevoice.src/internal/engine/engine_darwin.go` - X-ASR streaming engine 实现 `ReleaseTailCaptureDelay()`。 - X-ASR 松键尾采延迟为 `300ms`。 - `privatevoice.src/app.go` - `replaceEngine()` 时缓存 tail delay 到 `releaseTailCaptureNanos`,停止录音路径不再抢 `engineMu`。 - hold/tap 正常停止时先等待尾采,再 `StopAndGetSamples()`。 - `HasVoiceActivity()` 改到尾采和停止录音之后读取。 - 增加 `isStoppingRecording`,尾采未完成时阻止下一次录音启动,避免连续触发串音或设备状态竞争。 - 取消路径和静音自动停止路径不新增尾采延迟。 - `privatevoice.src/app_live_caption_test.go` - 覆盖 tail delay 缓存、非 tail engine 默认 0、尾采期间 hold/tap 不启动新录音。 - `privatevoice.src/internal/engine/engine_darwin_test.go` - 覆盖 X-ASR 请求 300ms tail delay、离线 sherpa engine 不实现 tail capture。 ## 代码审核 ### 审核员 1 第一轮发现阻塞问题: - 停止录音路径读取 `engineMu`,可能与实时字幕/识别锁形成录音生命周期竞态。 - `hasVoice` 在尾采前快照,尾采期间捕获到的语音可能不参与 VAD。 已修复后第二轮复审: - P1 已关闭:停止路径只读 atomic 缓存,不再拿 `engineMu`;`isStoppingRecording` 阻止尾采期间新录音。 - P2 已关闭:先 `StopAndGetSamples()`,再读取 `HasVoiceActivity()`。 - 无新的 P1/P2。 - 建议补测 `isStoppingRecording`,已补。 ### 审核员 2 第一轮无阻塞,指出: - `releaseTailCaptureDelay()` 等 `engineMu` 有可感知延迟风险。 - VAD 读取过早。 - 自动化测试偏结构性。 已修复后第二轮复审: - 无阻塞问题。 - 确认 X-ASR 隔离、atomic 缓存、VAD 顺序和连续触发保护成立。 - 非阻塞观察:录音中切模型可能存在极短暂 delay/engine 不一致,建议以后在模型切换入口禁止录音中切换。 ## QA 结果 自动化 QA 通过,未使用临时 GUI/AX/cliclick/screencapture 命令。 本地执行: - `go test ./...`:通过;仅有既有 macOS / onnxruntime 最低系统版本链接 warning。 - `go test -race . ./internal/engine ./internal/audio ./internal/input`:通过。 - `go test -race -count=20 -run 'TestStartRecordingIgnoredWhileStoppingRecording|TestStartTapRecordingIgnoredWhileStoppingRecording|TestReleaseTailCapture' .`:通过。 - `npm run build`:通过;仅有既有 Svelte a11y warning。 - `./scripts/build-local-macos.sh arm64`:通过,签名与 DMG verify 成功。该构建未安装到 `/Applications`,且未递增 build,因此仅作为构建验证证据。 QA 角色独立结论: - 自动化 QA 通过,未发现阻塞问题。 - 确认 X-ASR 有 300ms release tail,非 X-ASR 无 tail。 - 确认停止录音不再依赖 `engineMu`。 - 确认 `isStoppingRecording` 覆盖连续快速触发风险。 - 确认 VAD 在尾采后判断。 ## 未自动化覆盖 真实语音尾字效果需要用户拿后续测试包做人工验证: - X-ASR hold 模式反复说:“技术总监让我问你一下”“你看一下”“确认一下”“可以了”“好了呀”。 - 三种松键节奏:最后一个字刚出口就松、提前一点松、说完后再松。 - X-ASR tap 模式同样覆盖这些句子。 - 极短句 VAD:“好”“一下”“嗯”“可以”。 - 连续快速两次输入,间隔 0.5-1 秒,确认不串音、不丢下一句。 - 实时字幕开启时,确认最终上屏保留尾字,动效不冻结。 - 非 X-ASR 至少测 SenseVoice / Qwen3-ASR,确认没有 300ms 可感知新增延迟。 ## 备注 当前工作区存在大量与本次修复无关的 Release 产物、文档、AGENTS 等未提交/未跟踪变动。本次提交必须只包含上述源码、测试与本记录,不得混入无关产物。