Confirmed Architecture Baseline · 2026-07-14

一个进程完成录音、存储、AI、API 与桌面生命周期

首个桌面版本移除 Express 与 Node sidecar。React 保留为界面,Tauri/Rust 成为唯一运行核心;外接 SSD 是可拔出的归档盘,而不是系统运行的前提。

D-01
Rust 直接采集音频

录音脱离 WebView,后台隐藏、休眠唤醒不再依赖浏览器计时器。

D-02
首版即无 Express

Axum 保留原 HTTP 合同;产品包中没有 Node、sidecar、双进程守护。

D-03
本地先落盘

每个完整片段先进入本地 spool,再校验迁入 SSD,拔盘不会打断录音。

D-04
SQLite 常驻内置盘

文字、事件、迁移状态始终可用;SSD 离线只影响已归档媒体回放。

01
System Architecture

Rust 一体化桌面架构

这张图只回答“有哪些运行单元、谁调用谁”。录音、存储和 AI 都在同一 Rust 进程;React 与树莓派统一通过 Axum 提供的合同访问服务。

GROWLOG.APP · SINGLE RUST PROCESS React / Vite 界面窗口、菜单栏状态、手机页面 Tauri Shell生命周期 Axum HTTP / SSE:4000 · UI / LAN / 树莓派合同 Audio EngineCPAL · Ring Buffer · WAV Chunker高优先级回调不碰磁盘和网络 App State任务与状态 Domain ServicesEvents · Search · Stats · Profile保持现有请求与响应形状 Local Spool先封口,再迁移拔盘继续录制 SQLite Catalog元数据与状态机始终留在内置盘 WorkersArchive · Azure · Import失败可重试,不阻塞录音 外部调用方树莓派 Motion手机 / LAN 浏览器现有 E2E 合同HTTP · POST /api/motion 外部系统SSD2T ArchiveAzure OpenAIDiskArbitrationAPFS · HTTPS · macOS Framework Tauri IPCHTTP / SSEPCM · sealed chunksdomain callsHTTP contractcopy + verify
界面与 APIRust 服务数据库本地缓冲外部系统
React / Vite

桌面窗口与手机页面

Axum HTTP / SSE

保持现有 API 合同

Rust Core

录音、存储、AI、领域服务

SQLite + Local Spool

元数据常驻,音频先落本地

SSD2T + Azure

归档大文件,执行 AI 分析

首个桌面交付物不包含 Express

旧服务只作为合同对照和历史数据来源;不会被 Tauri 启动,也不会进入安装包。

02
Storage Continuity

拔盘继续录,插盘自动清空积压

外接盘不再承担“在线数据库”的角色。录音先在内置盘封口,迁移线程复制、校验、原子改名后才删除本地原件。

内置盘 · 永远在线

元数据中枢catalog.db
当前与积压录音spool/
配置与密钥引用settings/
低空间保护free-space gate

SSD2T · 可拔归档盘

长期录音audio/
图片与动态检测motion/ · photos/
旧 JSONLlegacy-jsonl/
数据库快照backups/
CAPTURING正在写本地临时片段
SEALEDWAV 已完整关闭
COPYING复制为 SSD .partial
VERIFYING大小与 hash 对齐
ARCHIVED原子改名并删本地
01SSD 拔出

DiskArbitration 立刻标记离线,停止迁移,不影响录音线程。

02本地积累

完整片段按状态进入 spool,UI 显示本地暂存量。

03SSD 插入

按 Volume UUID 确认是目标盘,不认同名假盘。

04后台排空

从最旧片段开始复制;录音优先,迁移限速。

05完成归档

校验后更新 SQLite 路径,再删除本地原件。

不能承诺无限离线录音

内置盘空间有限。系统应持续录制到安全阈值;接近阈值先提醒,低于硬门槛时暂停新录音,禁止把系统盘写满。

03
Compatibility Contract

换掉发动机,不换现有插头

Axum 保持现有请求路径和响应形状,让 React、树莓派、手机和现有 E2E 继续使用。内部实现从文件扫描切换为 SQLite。

实时与采集

GET /api/streamPOST /api/motionPOST /api/transcribePOST /api/analyzePOST /api/record

查询与内容

GET /api/datesGET /api/eventsGET /api/logsGET /api/statsGET /api/reportGET /api/export

设置与维护

GET/PUT /api/profileGET/PUT /api/ai-configPOST /api/ai-config/testPUT/DELETE /api/events/:idGET /health

明确否定

  • Tauri 只套壳,录音仍在 WebView
  • Rust 录音 + Express 永久双后端
  • 整个 logs 目录永远软链接到 SSD
  • 拔盘时把正在写的文件切到另一条路径

已确认方案

  • Rust 直接采集并切片
  • Axum 承接全部旧 API 合同
  • SQLite 常驻内置盘,SSD 只归档大文件
  • 本地先封口,复制校验后迁移
04
Work Packages · Not Dispatched

12 个可直接交给 CC 的工作包

每包都定义交付物、依赖和机器可验收标准。规模用 S/M/L 表示相对复杂度,不承诺天数;WP-00 技术探针完成后再校准。

WAVE 0证据与地基WP-00 · 01
WAVE 1数据与存储WP-02 · 03
WAVE 2录音与 APIWP-04 · 05 · 06
WAVE 3AI 与桌面WP-07 · 08 · 09
WAVE 4迁移与验收WP-10 · 11
WP-00

技术探针与合同冻结

先证明 ARM64、音频、Axum、SQLite、SSD 监听组合能跑。

尚未派发
Owner · CCSize · M依赖 · 无
原生 ARM64 工具链、最小 Tauri App、CPAL 10 分钟录音探针、Axum health、DiskArbitration appear/disappear 证据、现有 API fixture。
  • 产物为 arm64,不再调用 x86_64 rustc
  • 隐藏窗口后录音持续,样本时长连续
  • SSD 拔插事件能按 UUID 被识别
为什么必须先做

这五个前提任一不成立,后续大迁移都会建立在假设上。探针只验证,不写业务实现。

WP-01

Rust 工作区与单进程骨架

Tauri 启动同进程 Axum,建立可取消的后台任务。

尚未派发
Owner · CCSize · M依赖 · WP-00
Rust workspace、共享 AppState、Axum :4000、React 静态资源、graceful shutdown、单实例。
  • 双击 App 后同一进程同时提供 UI 与 /health
  • 退出 App 后端口释放、后台任务退出
  • 安装包中不包含 Node 与 Express
WP-02

SQLite 领域模型与迁移框架

建立事件、日志、媒体、任务和存储状态的唯一事实源。

尚未派发
Owner · CCSize · L依赖 · WP-01
版本化 migrations、repositories、FTS5、软删除、media_location 与 processing_job 状态。
  • 事务失败可回滚,重启后状态不丢
  • 事件搜索、日期统计和媒体路径有索引
  • 数据库固定在 Application Support
WP-03

本地 Spool 与 SSD 归档状态机

实现拔盘继续录、插盘自动迁移的核心保证。

尚未派发
Owner · CCSize · L依赖 · WP-02
磁盘监听、UUID 校验、.partial 复制、hash 验证、原子改名、重试、限速、空间阈值。
  • 迁移中拔盘,本地原件仍存在
  • 重新插入后自动恢复并排空积压
  • 错误磁盘同名也不会被接受
WP-04

Rust Audio Engine

用 CoreAudio/CPAL 替代浏览器 getUserMedia 与 AudioWorklet。

尚未派发
Owner · CCSize · L依赖 · WP-03
设备选择、Ring Buffer、WAV chunker、暂停/恢复、设备断开重连、录音状态事件。
  • 音频回调不做磁盘与网络 I/O
  • 连续片段无明显时间缺口
  • 窗口隐藏和前后台切换不影响录音
WP-05

Axum 读取与媒体 API

优先迁移无副作用的查询、统计和媒体回放合同。

尚未派发
Owner · CCSize · M依赖 · WP-02
dates/events/logs/stats/report/export/health 与媒体 range 请求。
  • 旧 fixture 与新响应结构一致
  • 音频支持浏览器拖动与断点读取
  • SSD 离线时返回明确 media-offline 状态
WP-06

写入、Motion 与实时推送 API

保住手机、树莓派和现有 E2E 的外部合同。

尚未派发
Owner · CCSize · L依赖 · WP-02 · 05
record/motion/event edit-delete/profile/config、API key、rate limit、SSE。
  • 现有 motion_detector_client.sh 无需改合同
  • 写入成功后 SSE 立即推送前端
  • 未授权写请求被拒绝,读取策略明确
WP-07

Azure Rust Client 与分析 Worker

迁移转写、音频分析、日总结与可恢复任务队列。

尚未派发
Owner · CCSize · L依赖 · WP-02 · 04
reqwest clients、超时、重试、幂等 job、三组配置测试、错误分类。
  • 断网不阻塞录音,任务进入可重试状态
  • 重启后不会重复生成同一事件
  • 真实音频能得到 transcript 与 event
WP-08

React 桌面状态与录音切换

删除浏览器录音链路,界面改读 Rust 运行状态。

尚未派发
Owner · CCSize · M依赖 · WP-04 · 05 · 06
Rust 录音控制、SSD 状态、本地积压、迁移进度、AI 队列、媒体离线提示。
  • 前端不再调用 getUserMedia
  • 30 秒内能看懂当前录音与存储状态
  • 浏览器 LAN 模式仍能只读访问
WP-09

菜单栏、开机启动与生命周期

把 GrowLog 变成真正的后台桌面服务。

尚未派发
Owner · CCSize · M依赖 · WP-01 · 04 · 08
Tray、隐藏窗口、启动项、单实例、真正退出、错误提示、麦克风权限文案。
  • 关闭窗口后录音继续
  • 菜单栏能暂停、恢复、打开主窗口
  • 真正退出时 WAV 正常封口并释放设备
WP-10

历史 JSONL 导入与存储切换

把既有文本和媒体路径导入 SQLite,保留原始档案。

尚未派发
Owner · CCSize · L依赖 · WP-02 · 03 · 05
dry-run importer、去重、路径映射、数量对账、legacy-jsonl 归档、旧软链接退出方案。
  • 导入前后日期、事件、日志数量可对账
  • 随机抽样音频都能回放
  • 原 JSONL 不删除,转为只读历史备份
WP-11

故障注入、长跑与发行 Gate

用真实故障证明核心价值,而不是只跑 happy path。

尚未派发
Owner · CC + HermesSize · L依赖 · 全部
长跑报告、拔插盘报告、断网/崩溃恢复、签名安装包、回滚包、用户操作说明。
  • 长时间隐藏窗口录音无中断
  • 迁移中拔盘与重启都不丢原件
  • Express 与 Node 依赖从发行产物中消失
05
MCP · Claude Code Dispatch

先过 Gate,再续同一会话推进

工作包不是一次把 12 项全塞给 CC。先派 WP-00 拿真实证据,再按 Wave 推进;连续包必须复用 session_id,让 CC 继承前一包的代码与决定。

派发波次

WAVE 0

WP-00 → Gate 0。只验证组合前提;失败就修正架构,不进入业务实现。

WAVE 1

WP-01 → 02 → 03。先建立单进程、数据库和存储连续性。

WAVE 2

WP-04 与 WP-05 可在边界稳定后分工;WP-06 随后收口写入与 SSE。

WAVE 3

WP-07 → 08 → 09。AI、界面与桌面生命周期串成完整用户体验。

WAVE 4

WP-10 → 11。导入历史数据并执行故障注入,Gate 全过才发行。

CC 派发契约

  • 全部通过 MCP bridge 派发;每包返回 task_id 与可恢复 session_id。
  • 同项目连续迭代复用同一 session_id,不让 CC 每包重新摸仓库。
  • 每个工作包独立 commit;Gate 失败直接修当前包,不越级进入下个 Wave。
  • CC 自报完成不算验收;Hermes 复跑合同测试、故障注入与真实录音。
  • 首轮 prompt 只派 WP-00;本页 Review 通过前不派任何编码任务。
06
Gates & Risks

五道 Gate 挡住“代码能跑但产品不可靠”

每一道 Gate 都需要真实环境证据。编译成功、单测通过、CC 报告完成,都不能代替核心路径验收。

风险级别触发证据必须应对
当前 Rust 工具链是 x86_64,而目标 Mac 与 Node 为 arm64HIGHWP-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 离线过久耗尽本地空间MEDspool 增长、系统盘进入阈值软提醒 + 硬暂停 Gate;绝不把系统盘写满。
Azure 故障拖垮录音主链MED分析队列积压但录音受影响录音与分析完全解耦,幂等任务可重试。
GATE 0技术组合成立ARM64 · CPAL · SSD event
GATE 1数据不会丢SQLite · spool · archive
GATE 2合同不漂移现有 API · motion · SSE
GATE 3用户真的能用tray · hidden · LAN
GATE 4故障后可恢复拔盘 · 断网 · crash