baa-conductor

git clone 

baa-conductor / tasks
codex@macbookpro  ·  2026-03-30

T-S058.md

  1# Task T-S058:消息同步任务生成续命任务
  2
  3## 状态
  4
  5- 当前状态:`已完成`
  6- 规模预估:`M`
  7- 依赖任务:`T-S055`、`T-S056`、`T-S057`
  8- 建议执行者:`Codex` 或 `Claude`
  9
 10## 直接给对话的提示词
 11
 12`/Users/george/code/baa-conductor/tasks/T-S058.md` 任务文档,完成开发任务。
 13
 14如需补背景,再读:
 15
 16- `/Users/george/code/baa-conductor/plans/discuss/DISCUSS-TIMED-JOBS-RENEWAL-REQUIREMENTS.md`
 17- `/Users/george/code/baa-conductor/tasks/T-S055.md`
 18- `/Users/george/code/baa-conductor/tasks/T-S056.md`
 19- `/Users/george/code/baa-conductor/tasks/T-S057.md`
 20
 21## 当前基线
 22
 23- 仓库:`/Users/george/code/baa-conductor`
 24- 分支基线:`main`
 25- 提交:`071abbf`
 26
 27## 分支与 worktree(强制)
 28
 29- 分支名:`feat/renewal-message-projector`
 30- worktree 路径:`/Users/george/code/baa-conductor-renewal-message-projector`
 31
 32开工步骤:
 33
 341. `cd /Users/george/code/baa-conductor`
 352. `git worktree add ../baa-conductor-renewal-message-projector -b feat/renewal-message-projector main`
 363. `cd ../baa-conductor-renewal-message-projector`
 374. 在这个 worktree 目录里开发,不要回到主仓库目录
 38
 39完成后提交与推送:
 40
 411. 在 worktree 里提交所有变更(包括更新后的任务文档)
 422. `git push -u origin feat/renewal-message-projector`
 43
 44合并步骤(由合并者执行):
 45
 461. `cd /Users/george/code/baa-conductor`
 472. `git fetch origin`
 483. `git merge origin/feat/renewal-message-projector`
 494. `git push`
 505. `git worktree remove ../baa-conductor-renewal-message-projector`(如果 worktree 还在)
 51
 52合并冲突处理:
 53
 541. 如果 `git merge` 报冲突,先 `git diff` 查看冲突文件
 552. 手动解决冲突后 `git add` 冲突文件
 563. `git merge --continue` 完成合并
 574. 不要用 `git merge --abort` 然后 force 覆盖
 58
 59命名规则:
 60
 61- 功能任务分支名以 `feat/` 开头
 62- 缺陷任务分支名以 `bug/` 开头
 63
 64## 目标
 65
 66实现“消息同步任务”:定时扫描旧消息,按照对话自动化状态和可用路由规则,生成续命任务。
 67
 68## 背景
 69
 70当前共识已经排除了“在 ingest 末尾直接发续命”的做法。首版需要一个独立的 projector,把消息事实和续命执行解耦开。
 71
 72## 涉及仓库
 73
 74- `/Users/george/code/baa-conductor`
 75
 76## 范围
 77
 78- 实现消息扫描与游标推进
 79- 实现 `shouldRenew()` 和 payload 构建
 80- 将满足条件的消息幂等投影到 `renewal_jobs`
 81- 不实现实际发送
 82
 83## 路径约束
 84
 85- 不要把 projector 做成“消息到达即同步”的直接 hook
 86- 必须通过 timed-jobs 框架运行
 87- 必须遵守小批量和 settle delay 约束
 88
 89## 推荐实现边界
 90
 91建议优先做:
 92
 93- `apps/conductor-daemon/src/timed-jobs/`
 94- `apps/conductor-daemon/src/renewal/`
 95- 必要时最小改动 `apps/conductor-daemon/src/instructions/ingest.ts` 以补齐消息元数据
 96
 97## 允许修改的目录
 98
 99- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/timed-jobs/`
100- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/renewal/`
101- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/`
102- `/Users/george/code/baa-conductor/packages/artifact-db/`
103
104## 尽量不要修改
105
106- `/Users/george/code/baa-conductor/plugins/`
107- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/local-api.ts`
108
109## 必须完成
110
111### 1. 消息扫描
112
113- 只扫描“旧消息”
114- 每轮最多处理约 `10`115- 支持可配置 settle delay
116- 支持游标或等价机制,避免重复全表扫描
117
118### 2. 续命判断
119
120- 以对话状态 `manual / auto / paused` 为判断核心
121- 检查冷却时间
122- 检查重复消息
123- 检查当前目标路由是否可用
124
125### 3. 任务生成
126
127- 生成 `renewal_jobs`
128- 幂等,不为同一条消息重复生成任务
129- 写 projector 外部日志
130- 不执行发送
131
132## 需要特别注意
133
134- `paused``manual` 不应生成新任务
135- payload 构建不要写死成未来无法扩展的格式
136- 尽量把规则收敛成独立函数,避免散落在 runner 代码里
137- 所有开发必须在 worktree 中进行,不要在主仓库目录修改代码
138
139## 验收标准
140
141- auto 对话的新旧消息能生成 `pending` 续命任务
142- manual / paused 对话不会生成续命任务
143- 同一消息重复扫描不会生成重复任务
144- projector 执行过程会写外部日志
145
146## 推荐验证命令
147
148- `cd /Users/george/code/baa-conductor-renewal-message-projector && pnpm build`
149- `cd /Users/george/code/baa-conductor-renewal-message-projector && pnpm -C apps/conductor-daemon test`
150
151## 执行记录
152
153> 以下内容由执行任务的 AI 填写,创建任务时留空。
154
155### 开始执行
156
157- 执行者:`Codex`
158- 开始时间:`2026-03-30 16:00:12 CST`
159- 状态变更:`待开始` → `进行中`
160
161### 完成摘要
162
163- 完成时间:`2026-03-30 16:31:47 CST`
164- 状态变更:`进行中` → `已完成`
165- 修改了哪些文件:
166  - `apps/conductor-daemon/src/renewal/projector.ts`
167  - `apps/conductor-daemon/src/index.ts`
168  - `apps/conductor-daemon/src/timed-jobs/runtime.ts`
169  - `apps/conductor-daemon/src/index.test.js`
170  - `packages/artifact-db/src/schema.ts`
171  - `packages/artifact-db/src/store.ts`
172  - `packages/artifact-db/src/types.ts`
173  - `packages/artifact-db/src/index.ts`
174  - `packages/artifact-db/src/index.test.js`
175  - `tasks/T-S058.md`
176- 核心实现思路:
177  -`artifact-db` 增加按 `(observed_at, id)` 游标顺序扫描消息的 store 原语和索引,支持按 settle cutoff 增量扫描旧消息,避免重复全表扫描
178  - 新增 `renewal/projector.ts`,把消息到续命任务的投影逻辑收敛到独立 runner,包含 cursor 持久化、`shouldRenew()` 判断、结构化 payload / target snapshot 构建,以及 projector 过程日志
179  - projector 基于 `local_conversations``conversation_links` 判断 `manual / auto / paused`、冷却期、重复任务和目标路由可用性,仅为满足条件的消息生成幂等 `pending` `renewal_jobs`
180  -`ConductorRuntime` 启动时注册 `renewal.projector` 到 timed-jobs 框架,并把 shared timed-jobs log 目录暴露给 runner 以回写 `renewal_jobs.log_path`
181  - 用测试覆盖 cursor 扫描、manual / paused / cooldown / route unavailable 跳过、幂等投影、runtime 接线和重启后 cursor 持久化
182- 跑了哪些测试:
183  - `cd /Users/george/code/baa-conductor-renewal-message-projector && pnpm install`
184  - `cd /Users/george/code/baa-conductor-renewal-message-projector && pnpm -C packages/artifact-db test`
185  - `cd /Users/george/code/baa-conductor-renewal-message-projector && pnpm -C apps/conductor-daemon test`
186  - `cd /Users/george/code/baa-conductor-renewal-message-projector && pnpm build`
187
188### 执行过程中遇到的问题
189
190- 新 worktree 初始没有安装依赖,第一次跑测试直接失败于 `pnpm exec tsc` 找不到;补跑一次 `pnpm install` 后恢复正常构建和测试流程
191
192### 剩余风险
193
194- 当前 projector 主要依赖 `messages.conversation_id -> active conversation_links` 解析本地对话;如果未来 final-message 再次出现缺失 remote conversation 且无法从其他信号补齐的情况,这类消息会被记录为 skip,不会生成续命任务
195- 当前冷却期判断复用 `local_conversations.cooldown_until` 字段,但还没有单独的策略配置或自动写入逻辑;如果后续希望把“生成任务后自动推进冷却窗口”做成正式策略,需要在后续任务里补控制面配置