edit | blame | history | raw

Round 1 开发自查记录

状态:开发自查记录
所属子项目:02-P-NBL
Round:Round 1
日期:2026-06-02
对应文档:

1. 基本信息

项目 内容
分支 codex/round1-model-profile
commit id 由最终 QA 交接信息填写
研发负责人 Codex
自查日期 2026-06-02
App 版本 / build 未打包
macOS 版本 当前本机环境
芯片 当前本机环境

2. 本次实现范围

已完成:

  • 新增 ModelProfile / ModelRegistry
  • 新增 LanguageProfile / LanguageRegistry 最小实现。
  • 新增 RequiredFileRule,支持 AllOf / AnyOf
  • 新增 ModelInstallState,支持 models/state.json 读写。
  • 新增 ModelResolver,支持 state、新目录、旧目录 fallback。
  • 新增 ResolvedModel
  • 新增 sensevoice-zh profile。
  • config.Config 增加隐藏字段 SelectedModelID,默认 sensevoice-zh
  • engine.New() 保持外部兼容,内部改为通过 resolver 加载 selected/default model。
  • macOS/Linux/Windows 平台 engine 改为接收 ResolvedModel
  • 下载器改为临时下载、解压、staging 校验、安全安装到 models/sensevoice-zh
  • 下载流程已覆盖“primary 下载成功但解压/校验失败时继续尝试 fallback URL”。
  • 用户主动触发下载时,models/sensevoice-zh 可被 staging 校验通过的新模型安全替换;替换失败会尝试恢复 backup。
  • Resolver 已拒绝 state.json 中的绝对路径或逃逸 models 根目录的相对路径。
  • macOS engine 已使用 profile 中的 ProviderOrder
  • engine 初始化失败时会区分“缺模型”和“结构存在但不可加载”:后者发送 engine:status = error
  • 保留 EngineService.ModelExists()EngineService.DownloadModel(primaryURL, fallbackURL) 兼容签名。
  • 新增 EngineService.GetStatus(),用于前端补查可能早于订阅发生的 engine 状态。
  • Onboarding 已处理 engine:status = need_model 且带错误信息的场景。
  • 新增模型相关单元测试。

未做,符合 Round 1 非目标:

  • 未接入 Moonshine。
  • 未接入 Parakeet。
  • 未接入 Qwen3-ASR。
  • 未新增语言 UI。
  • 未新增模型选择 UI。
  • 未新增模型删除 UI。
  • 未自动迁移旧模型目录。

3. 变更文件

代码:

  • privatevoice.src/internal/model/profile.go
  • privatevoice.src/internal/model/registry.go
  • privatevoice.src/internal/model/validator.go
  • privatevoice.src/internal/model/install_state.go
  • privatevoice.src/internal/model/resolver.go
  • privatevoice.src/internal/model/downloader.go
  • privatevoice.src/internal/model/model_test.go
  • privatevoice.src/internal/engine/engine.go
  • privatevoice.src/internal/engine/engine_darwin.go
  • privatevoice.src/internal/engine/engine_linux.go
  • privatevoice.src/internal/engine/engine_windows.go
  • privatevoice.src/internal/config/config.go
  • privatevoice.src/internal/paths/paths.go

文档:

  • 02-P-NBL/round-1/prd.md
  • 02-P-NBL/round-1/engineering-tasks.md
  • 02-P-NBL/round-1/qa-test-plan.md
  • 02-P-NBL/round-1/dev-checklist.md
  • 02-P-NBL/round-1/dev-checklist-current.md
  • 02-P-NBL/round-1/qa-report-template.md
  • 02-P-NBL/round-1/README.md

4. 自动化验证

命令 结果 说明
cd privatevoice.src/frontend && npm run build 通过 存在既有 Svelte a11y warning,构建成功
cd privatevoice.src && go test ./internal/model -count=1 通过 强制重跑模型包测试,非缓存
cd privatevoice.src && go test ./... -count=1 通过 强制重跑全量 Go 测试,非缓存;新 checkout 需先完成前端构建以生成 frontend/dist

前端构建警告:

  • UpdateDialog.svelte 的 dialog focus / noninteractive listener 警告。
  • ToggleSwitch.svelte 的 button aria label 警告。

这些警告不由本轮改动引入,本轮未修改相关组件。

5. 已覆盖的自动化场景

  • 默认 model profile 为 sensevoice-zh
  • 未知 model id 返回错误。
  • AnyOf 规则允许 model.onnx
  • model.int8.onnx 优先于 model.onnx
  • 缺少 tokens.txt 时校验失败。
  • 0 字节模型文件校验失败。
  • 无 state 时旧 models/sensevoice 可解析。
  • 无 state 时新旧目录都存在,优先新 models/sensevoice-zh
  • 非法 state.json 时 fallback 到旧目录。
  • state 指向坏目录时 fallback 到旧目录。
  • state 指向绝对路径或逃逸 models 根目录的路径时被拒绝并 fallback。
  • 不完整目录返回 installed_incomplete
  • state round trip。
  • 下载失败不删除旧模型目录。
  • primary 坏包时尝试 fallback URL。
  • bad archive 不写入 installed state。
  • 用户触发下载可替换已有 models/sensevoice-zh

6. 未完成验证

以下需要 QA 在真机或测试包阶段执行:

  • 真实 SenseVoice 模型下载。
  • 真实模型初始化。
  • 真实录音识别。
  • replacement 在真实识别链路中生效。
  • 历史记录真实写入。
  • macOS 麦克风权限未授权/已授权回归。
  • 断网已有模型完整使用。
  • 网络观察确认识别阶段无上传。
  • 菜单栏、Dock、窗口层级、全屏、Split View smoke。

7. 移交 QA 结论

开发自查结论:

可进入 QA 预检。

说明:

代码级自动化测试和前端构建已通过,但尚未打包,也尚未执行真机真实模型回归。
根据项目交付门禁,本状态不能直接交付用户验收,需要 QA 按 qa-test-plan.md 继续验证。