RFC: Stateful Sense — 有状态 Sense 重构 #308

Closed
opened 2026-05-01 09:38:06 +00:00 by xiaoju · 0 comments
Owner

背景

当前 Sense 是无状态的采样函数,返回 ComputeResult<T>(null 或 signal + workflow trigger),状态管理散落在各 Sense 自己操作 SQLite 里。Signal Bus 作为中间层增加了复杂度但实际只起 log 作用。

问题

  • Sense 要自己管理状态(读写 DB),compute 函数不纯
  • Signal 作为独立概念意义不大,主要是 log
  • 链路 Sense → Signal → Workflow 多了一跳

目标

把 Sense 重构为有状态的定时副作用(stateful reducer):

type SenseDefinition<S> = {
  name: string;
  initialState: S;
  compute: (state: S) => {
    state: S;
    workflow: WorkflowTrigger | null;
  };
};

每次定时触发时,引擎传入上一轮 state,compute 返回新 state + 可选的 workflow trigger。

简化后的链路

External World → Sense(state) → { newState, workflow? } → Workflow → Log

关键设计决策

  1. 移除 Signal — Signal Bus 不再需要,workflow trigger 直接从 compute 返回
  2. State 持久化 — 每个 Sense 一个 JSON 文件,不需要 SQLite
  3. 初始状态 — initialState 在 SenseDefinition 中定义,读不到 state.json 时使用
  4. Crash recovery — 每次 compute 完立即写回 state.json,重启从文件恢复

Phase 拆分

Phase 1: 核心类型重构

  • 新增 SenseDefinition 类型(含 initialState + compute 签名)
  • 更新 ComputeResult → 新签名
  • 移除 Signal 相关类型
  • 验证目标:类型编译通过,类型体系自洽

Phase 2: 引擎层适配

  • State 持久化(JSON 文件读写)
  • Sense runtime 传入 state、写回 state
  • 移除 Signal Bus
  • 验证目标:daemon 能加载 Sense、执行 compute、持久化 state

Phase 3: 现有 Sense 迁移

  • 迁移所有现有 Sense 到新签名
  • 清理旧 SQLite 相关代码
  • 验证目标:所有现有 Sense 正常运行

Phase 4: 清理

  • 移除 Signal Bus 代码、Signal 相关模块
  • 更新文档(CLAUDE.md、README)
  • 验证目标:无残留代码,文档一致

完成标准

  • 所有 Phase 的 testing issue 已 close
  • 现有 Sense 全部迁移完成
  • 文档更新
## 背景 当前 Sense 是无状态的采样函数,返回 `ComputeResult<T>`(null 或 signal + workflow trigger),状态管理散落在各 Sense 自己操作 SQLite 里。Signal Bus 作为中间层增加了复杂度但实际只起 log 作用。 ### 问题 - Sense 要自己管理状态(读写 DB),compute 函数不纯 - Signal 作为独立概念意义不大,主要是 log - 链路 Sense → Signal → Workflow 多了一跳 ## 目标 把 Sense 重构为有状态的定时副作用(stateful reducer): ```typescript type SenseDefinition<S> = { name: string; initialState: S; compute: (state: S) => { state: S; workflow: WorkflowTrigger | null; }; }; ``` 每次定时触发时,引擎传入上一轮 state,compute 返回新 state + 可选的 workflow trigger。 ### 简化后的链路 ``` External World → Sense(state) → { newState, workflow? } → Workflow → Log ``` ## 关键设计决策 1. **移除 Signal** — Signal Bus 不再需要,workflow trigger 直接从 compute 返回 2. **State 持久化** — 每个 Sense 一个 JSON 文件,不需要 SQLite 3. **初始状态** — initialState 在 SenseDefinition 中定义,读不到 state.json 时使用 4. **Crash recovery** — 每次 compute 完立即写回 state.json,重启从文件恢复 ## Phase 拆分 ### Phase 1: 核心类型重构 - 新增 SenseDefinition<S> 类型(含 initialState + compute 签名) - 更新 ComputeResult → 新签名 - 移除 Signal 相关类型 - 验证目标:类型编译通过,类型体系自洽 ### Phase 2: 引擎层适配 - State 持久化(JSON 文件读写) - Sense runtime 传入 state、写回 state - 移除 Signal Bus - 验证目标:daemon 能加载 Sense、执行 compute、持久化 state ### Phase 3: 现有 Sense 迁移 - 迁移所有现有 Sense 到新签名 - 清理旧 SQLite 相关代码 - 验证目标:所有现有 Sense 正常运行 ### Phase 4: 清理 - 移除 Signal Bus 代码、Signal 相关模块 - 更新文档(CLAUDE.md、README) - 验证目标:无残留代码,文档一致 ## 完成标准 - [ ] 所有 Phase 的 testing issue 已 close - [ ] 现有 Sense 全部迁移完成 - [ ] 文档更新
This repo is archived. You cannot comment on issues.
No Label
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/nerve#308