技术探针与合同冻结
先证明 ARM64、音频、Axum、SQLite、SSD 监听组合能跑。
- 产物为 arm64,不再调用 x86_64 rustc
- 隐藏窗口后录音持续,样本时长连续
- SSD 拔插事件能按 UUID 被识别
为什么必须先做
这五个前提任一不成立,后续大迁移都会建立在假设上。探针只验证,不写业务实现。
首个桌面版本移除 Express 与 Node sidecar。React 保留为界面,Tauri/Rust 成为唯一运行核心;外接 SSD 是可拔出的归档盘,而不是系统运行的前提。
录音脱离 WebView,后台隐藏、休眠唤醒不再依赖浏览器计时器。
Axum 保留原 HTTP 合同;产品包中没有 Node、sidecar、双进程守护。
每个完整片段先进入本地 spool,再校验迁入 SSD,拔盘不会打断录音。
文字、事件、迁移状态始终可用;SSD 离线只影响已归档媒体回放。
这张图只回答“有哪些运行单元、谁调用谁”。录音、存储和 AI 都在同一 Rust 进程;React 与树莓派统一通过 Axum 提供的合同访问服务。
桌面窗口与手机页面
保持现有 API 合同
录音、存储、AI、领域服务
元数据常驻,音频先落本地
归档大文件,执行 AI 分析
旧服务只作为合同对照和历史数据来源;不会被 Tauri 启动,也不会进入安装包。
外接盘不再承担“在线数据库”的角色。录音先在内置盘封口,迁移线程复制、校验、原子改名后才删除本地原件。
catalog.dbspool/settings/free-space gateaudio/motion/ · photos/legacy-jsonl/backups/DiskArbitration 立刻标记离线,停止迁移,不影响录音线程。
完整片段按状态进入 spool,UI 显示本地暂存量。
按 Volume UUID 确认是目标盘,不认同名假盘。
从最旧片段开始复制;录音优先,迁移限速。
校验后更新 SQLite 路径,再删除本地原件。
内置盘空间有限。系统应持续录制到安全阈值;接近阈值先提醒,低于硬门槛时暂停新录音,禁止把系统盘写满。
Axum 保持现有请求路径和响应形状,让 React、树莓派、手机和现有 E2E 继续使用。内部实现从文件扫描切换为 SQLite。
GET /api/streamPOST /api/motionPOST /api/transcribePOST /api/analyzePOST /api/recordGET /api/datesGET /api/eventsGET /api/logsGET /api/statsGET /api/reportGET /api/exportGET/PUT /api/profileGET/PUT /api/ai-configPOST /api/ai-config/testPUT/DELETE /api/events/:idGET /health每包都定义交付物、依赖和机器可验收标准。规模用 S/M/L 表示相对复杂度,不承诺天数;WP-00 技术探针完成后再校准。
先证明 ARM64、音频、Axum、SQLite、SSD 监听组合能跑。
这五个前提任一不成立,后续大迁移都会建立在假设上。探针只验证,不写业务实现。
Tauri 启动同进程 Axum,建立可取消的后台任务。
建立事件、日志、媒体、任务和存储状态的唯一事实源。
实现拔盘继续录、插盘自动迁移的核心保证。
用 CoreAudio/CPAL 替代浏览器 getUserMedia 与 AudioWorklet。
优先迁移无副作用的查询、统计和媒体回放合同。
保住手机、树莓派和现有 E2E 的外部合同。
迁移转写、音频分析、日总结与可恢复任务队列。
删除浏览器录音链路,界面改读 Rust 运行状态。
把 GrowLog 变成真正的后台桌面服务。
把既有文本和媒体路径导入 SQLite,保留原始档案。
用真实故障证明核心价值,而不是只跑 happy path。
工作包不是一次把 12 项全塞给 CC。先派 WP-00 拿真实证据,再按 Wave 推进;连续包必须复用 session_id,让 CC 继承前一包的代码与决定。
WP-00 → Gate 0。只验证组合前提;失败就修正架构,不进入业务实现。
WP-01 → 02 → 03。先建立单进程、数据库和存储连续性。
WP-04 与 WP-05 可在边界稳定后分工;WP-06 随后收口写入与 SSE。
WP-07 → 08 → 09。AI、界面与桌面生命周期串成完整用户体验。
WP-10 → 11。导入历史数据并执行故障注入,Gate 全过才发行。
每一道 Gate 都需要真实环境证据。编译成功、单测通过、CC 报告完成,都不能代替核心路径验收。
| 风险 | 级别 | 触发证据 | 必须应对 |
|---|---|---|---|
| 当前 Rust 工具链是 x86_64,而目标 Mac 与 Node 为 arm64 | HIGH | WP-00 binary/file 检查 | 先建立原生 ARM64 工具链,禁止 Rosetta 产物进入主线。 |
| 音频回调被文件或网络 I/O 阻塞 | HIGH | 长跑出现缺口或 buffer overrun | 回调只写 Ring Buffer;磁盘和 AI 全在独立 worker。 |
| 迁移中拔盘导致半文件或误删本地原件 | HIGH | 故障注入后 hash 不一致 | .partial + 校验 + 原子 rename;ARCHIVED 前不删本地。 |
| 历史 JSONL 导入漏数据或重复事件 | HIGH | 日期/事件/日志数量不一致 | dry-run、稳定 ID 去重、原始 JSONL 只读保留。 |
| Rust 新 API 与旧前端合同漂移 | MED | 现有 E2E 或 fixture diff 失败 | WP-00 冻结合同;逐 endpoint golden test,不顺手重设计。 |
| SSD 离线过久耗尽本地空间 | MED | spool 增长、系统盘进入阈值 | 软提醒 + 硬暂停 Gate;绝不把系统盘写满。 |
| Azure 故障拖垮录音主链 | MED | 分析队列积压但录音受影响 | 录音与分析完全解耦,幂等任务可重试。 |