- commit
- 693b8af
- parent
- 6ea34e2
- author
- im_wower
- date
- 2026-03-28 17:40:23 +0800 CST
docs: add artifact static service task cards T-S039 through T-S042 - T-S039: Foundation (DB + static file gen + /artifact/ route) - T-S040: Pipeline integration (ingest/executor write + truncation) - T-S041: Query routes (/v1/messages, /v1/executions, /v1/sessions) - T-S042: D1 async adapter and sync queue - Update TASK_OVERVIEW with execution order and dependencies Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 files changed,
+689,
-6
+174,
-0
1@@ -0,0 +1,174 @@
2+# Task T-S039:Artifact 静态服务基础层
3+
4+## 状态
5+
6+- 当前状态:`待开始`
7+- 规模预估:`M`
8+- 依赖任务:无
9+
10+## 直接给对话的提示词
11+
12+读 `/Users/george/code/baa-conductor/tasks/T-S039.md` 任务文档,完成开发任务。
13+
14+如需补背景,再读:
15+
16+- `/Users/george/code/baa-conductor/plans/ARTIFACT_STATIC_SERVICE.md`
17+
18+## 当前基线
19+
20+- 仓库:`/Users/george/code/baa-conductor`
21+- 分支基线:`main`
22+- 提交:`6ea34e2`
23+
24+## 分支与 worktree(强制)
25+
26+每个任务必须使用独立的分支和 worktree,禁止直接在 main 上修改,禁止多个任务共用同一个 worktree。
27+
28+- 分支名:`feat/artifact-foundation`
29+- worktree 路径:`/Users/george/code/baa-conductor-artifact-foundation`
30+
31+开工步骤:
32+
33+1. `cd /Users/george/code/baa-conductor`
34+2. `git worktree add ../baa-conductor-artifact-foundation -b feat/artifact-foundation main`
35+3. `cd ../baa-conductor-artifact-foundation`
36+4. 在这个 worktree 目录里开发,不要回到主仓库目录
37+
38+完成后合并步骤:
39+
40+1. 在 worktree 里提交所有变更
41+2. `cd /Users/george/code/baa-conductor`
42+3. `git merge feat/artifact-foundation`
43+4. `git worktree remove ../baa-conductor-artifact-foundation`
44+
45+合并冲突处理:
46+
47+1. 如果 `git merge` 报冲突,先 `git diff` 查看冲突文件
48+2. 手动解决冲突后 `git add` 冲突文件
49+3. `git merge --continue` 完成合并
50+4. 不要用 `git merge --abort` 然后 force 覆盖
51+
52+## 目标
53+
54+新建 artifact 数据库(SQLite),建表,实现静态文件生成模块,在 conductor HTTP server 上挂载 `/artifact/` 路由和 `/robots.txt`。
55+
56+## 背景
57+
58+当前执行结果只能文本回送,大结果截断丢失,跨会话无法接续。需要把消息和执行结果持久化到数据库,同时生成可通过 HTTP GET 访问的静态文件。本任务是整个 Artifact 静态服务的基础层,后续任务依赖本任务的数据库和文件生成能力。
59+
60+## 涉及仓库
61+
62+- `/Users/george/code/baa-conductor`
63+
64+## 范围
65+
66+- 新建 artifact SQLite 数据库(独立于现有 packages/db)
67+- 建 messages、executions、sessions 三张表
68+- 实现静态文件生成模块(.txt + .json 双格式)
69+- conductor HTTP server 挂载 `/artifact/` 路由 serve 静态文件
70+- 挂载 `/robots.txt` 路由
71+
72+## 路径约束
73+
74+- 新数据库文件放在 `state/artifact.db`
75+- 静态文件目录放在 `state/artifacts/`
76+- 静态文件子目录:`state/artifacts/msg/`、`state/artifacts/exec/`、`state/artifacts/session/`
77+
78+## 推荐实现边界
79+
80+建议新增:
81+
82+- `packages/artifact-db/` — 新 package,artifact 数据库层
83+ - `src/schema.ts` — 建表 SQL
84+ - `src/store.ts` — CRUD 操作
85+ - `src/static-gen.ts` — 静态文件生成(.txt + .json)
86+ - `src/types.ts` — 类型定义
87+
88+建议修改:
89+
90+- `apps/conductor-daemon/src/local-api.ts` — 新增 `/artifact/` 和 `/robots.txt` 路由
91+
92+## 允许修改的目录
93+
94+- `/Users/george/code/baa-conductor/packages/` (新建 artifact-db)
95+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/local-api.ts` (加路由)
96+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/index.ts` (初始化数据库)
97+
98+## 尽量不要修改
99+
100+- `/Users/george/code/baa-conductor/packages/db/` (现有数据库,不动)
101+- `/Users/george/code/baa-conductor/plugins/` (插件不动)
102+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/` (T-S040 的范围)
103+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/artifacts/` (T-S040 的范围)
104+
105+## 必须完成
106+
107+### 1. 新建 artifact 数据库和表
108+
109+- 新建 `packages/artifact-db/` package
110+- 建 `messages` 表:id, platform, conversation_id, role, raw_text, summary, observed_at, static_path, page_url, page_title, organization_id, created_at
111+- 建 `executions` 表:instruction_id, message_id, target, tool, params, params_kind, result_ok, result_data, result_summary, result_error, http_status, executed_at, static_path, created_at
112+- 建 `sessions` 表:id, platform, conversation_id, started_at, last_activity_at, message_count, execution_count, summary, created_at
113+- 提供 CRUD 方法:insertMessage, insertExecution, upsertSession, getMessage, getExecution, listMessages, listExecutions, listSessions, getLatestSessions
114+- 表结构参见 `plans/ARTIFACT_STATIC_SERVICE.md` 第 4 节
115+
116+### 2. 实现静态文件生成
117+
118+- 写入数据库时同步生成 `.txt` + `.json` 两个文件
119+- `.txt` 格式:frontmatter 元数据 + `---` 分隔 + 正文(参见方案文档第 6 节)
120+- `.json` 格式:完整 JSON 对象(参见方案文档第 6 节)
121+- 文件路径用 ID 命名:`state/artifacts/msg/{id}.txt`、`state/artifacts/exec/{id}.txt`
122+- Content-Type:`.txt` 返回 `text/plain; charset=utf-8`,`.json` 返回 `application/json; charset=utf-8`
123+
124+### 3. 挂载 HTTP 路由
125+
126+- `/artifact/**` — 从 `state/artifacts/` 目录 serve 静态文件
127+- `/robots.txt` — 返回 `User-agent: *\nAllow: /artifact/\n`
128+- 不需要鉴权(当前公开访问)
129+- 文件不存在时返回 404
130+
131+## 需要特别注意
132+
133+- 新数据库是独立的 `state/artifact.db`,不要动现有的 `packages/db` 和相关 migration
134+- 静态文件生成必须是同步的(写库 → 写文件一起完成),不能异步延迟
135+- URL 中的 ID 使用 hash/UUID 格式,不用递增数字
136+- 本任务只建基础能力,不接入指令执行主链路(那是 T-S040 的事)
137+- 所有开发必须在 worktree 中进行,不要在主仓库目录修改代码
138+
139+## 验收标准
140+
141+- `packages/artifact-db/` 可以独立编译通过
142+- 调用 `insertMessage()` 后,`state/artifacts/msg/{id}.txt` 和 `.json` 文件存在且内容正确
143+- 调用 `insertExecution()` 后,`state/artifacts/exec/{id}.txt` 和 `.json` 文件存在且内容正确
144+- `curl http://100.71.210.78:4317/artifact/msg/{id}.txt` 返回 200 + 正确内容
145+- `curl http://100.71.210.78:4317/artifact/msg/{id}.json` 返回 200 + 正确 JSON
146+- `curl http://100.71.210.78:4317/robots.txt` 返回正确的 robots 内容
147+- 访问不存在的文件返回 404
148+
149+## 推荐验证命令
150+
151+- `cd /Users/george/code/baa-conductor-artifact-foundation && pnpm build`
152+- `cd /Users/george/code/baa-conductor-artifact-foundation && pnpm test`
153+- `curl http://100.71.210.78:4317/robots.txt`
154+- `curl http://100.71.210.78:4317/artifact/msg/test.txt`
155+
156+## 执行记录
157+
158+> 以下内容由执行任务的 AI 填写,创建任务时留空。
159+
160+### 开始执行
161+
162+- 执行者:
163+- 开始时间:
164+- 状态变更:`待开始` → `进行中`
165+
166+### 完成摘要
167+
168+- 完成时间:
169+- 状态变更:`进行中` → `已完成`
170+- 修改了哪些文件:
171+- 核心实现思路:
172+- 跑了哪些测试:
173+
174+### 剩余风险
175+
+162,
-0
1@@ -0,0 +1,162 @@
2+# Task T-S040:Artifact 接入指令执行主链路
3+
4+## 状态
5+
6+- 当前状态:`待开始`
7+- 规模预估:`M`
8+- 依赖任务:`T-S039`
9+
10+## 直接给对话的提示词
11+
12+读 `/Users/george/code/baa-conductor/tasks/T-S040.md` 任务文档,完成开发任务。
13+
14+如需补背景,再读:
15+
16+- `/Users/george/code/baa-conductor/plans/ARTIFACT_STATIC_SERVICE.md`
17+
18+## 当前基线
19+
20+- 仓库:`/Users/george/code/baa-conductor`
21+- 分支基线:`main`(T-S039 合并后)
22+- 提交:`<T-S039 合并后的提交>`
23+
24+## 分支与 worktree(强制)
25+
26+每个任务必须使用独立的分支和 worktree,禁止直接在 main 上修改,禁止多个任务共用同一个 worktree。
27+
28+- 分支名:`feat/artifact-pipeline`
29+- worktree 路径:`/Users/george/code/baa-conductor-artifact-pipeline`
30+
31+开工步骤:
32+
33+1. `cd /Users/george/code/baa-conductor`
34+2. `git worktree add ../baa-conductor-artifact-pipeline -b feat/artifact-pipeline main`
35+3. `cd ../baa-conductor-artifact-pipeline`
36+4. 在这个 worktree 目录里开发,不要回到主仓库目录
37+
38+完成后合并步骤:
39+
40+1. 在 worktree 里提交所有变更
41+2. `cd /Users/george/code/baa-conductor`
42+3. `git merge feat/artifact-pipeline`
43+4. `git worktree remove ../baa-conductor-artifact-pipeline`
44+
45+合并冲突处理:
46+
47+1. 如果 `git merge` 报冲突,先 `git diff` 查看冲突文件
48+2. 手动解决冲突后 `git add` 冲突文件
49+3. `git merge --continue` 完成合并
50+4. 不要用 `git merge --abort` 然后 force 覆盖
51+
52+## 目标
53+
54+将 artifact 数据库和静态文件生成接入 BAA 指令执行主链路:browser.final_message 到达时写入 messages 表,指令执行完成时写入 executions 表,回送 AI 时超长结果截断并附带 artifact URL。
55+
56+## 背景
57+
58+T-S039 建好了数据库和静态文件生成能力,但还没有接入实际的消息和指令流水线。本任务把这些能力串进 ingest → executor → delivery 主链路,让每条消息和每次执行都自动入库并生成可访问的 URL。
59+
60+## 涉及仓库
61+
62+- `/Users/george/code/baa-conductor`
63+
64+## 范围
65+
66+- ingest 收到 browser.final_message 时写入 messages 表 + 生成静态文件
67+- executor 执行完成后写入 executions 表 + 生成静态文件
68+- delivery 回送时:短结果内联全文 + URL,长结果截断前 500 字符 + URL
69+- 阈值和摘要长度可配置
70+- session 索引在写入时自动更新
71+
72+## 允许修改的目录
73+
74+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/` (ingest, executor, loop)
75+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/artifacts/` (upload-session, delivery)
76+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/index.ts` (注入 artifact store)
77+- `/Users/george/code/baa-conductor/packages/artifact-db/` (如需补方法)
78+
79+## 尽量不要修改
80+
81+- `/Users/george/code/baa-conductor/packages/db/` (现有数据库不动)
82+- `/Users/george/code/baa-conductor/plugins/` (插件不动)
83+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/local-api.ts` (T-S039 已加路由)
84+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/firefox-ws.ts` (尽量不动 WS 层)
85+
86+## 必须完成
87+
88+### 1. ingest 写入 messages 表
89+
90+- `browser.final_message` 到达 → 调用 `artifactStore.insertMessage()`
91+- 全量保存 raw_text(永不截断)
92+- 自动生成 summary(取前 500 字符)
93+- 自动生成静态文件
94+- 不阻塞现有 ingest 流程,写入失败只 log 不中断
95+
96+### 2. executor 写入 executions 表
97+
98+- 指令执行完成 → 调用 `artifactStore.insertExecution()`
99+- 全量保存 result_data(永不截断)
100+- 自动生成 result_summary
101+- 自动生成静态文件
102+- 不阻塞现有执行流程,写入失败只 log 不中断
103+
104+### 3. 回送截断 + URL 拼接
105+
106+- 配置项:`inlineThreshold`(默认 2000 字符)、`summaryLength`(默认 500 字符)
107+- 结果 ≤ 阈值:内联全文 + 末尾附 artifact URL
108+- 结果 > 阈值:前 N 字符 + `\n\n完整结果:{artifact_url}`
109+- URL 格式:`https://conductor.makefile.so/artifact/exec/{id}.txt`
110+- 配置通过环境变量或 conductor config 注入
111+
112+### 4. session 索引自动更新
113+
114+- 每次写入 message 或 execution 时,自动 upsert 对应 session
115+- session 按 (platform, conversation_id) 去重
116+- 更新 last_activity_at、message_count、execution_count
117+- 生成 `state/artifacts/session/latest.txt`(最近 20 个活跃 session)
118+
119+## 需要特别注意
120+
121+- 写入 artifact 数据库和生成静态文件不能阻塞指令执行主链路
122+- 如果 artifact 写入失败(磁盘满、权限问题),只 log 错误,不影响正常执行和 delivery
123+- 截断阈值和摘要长度必须可配置
124+- 回送给 AI 的 URL 必须是 exact URL(完整路径),不能让 AI 自己拼
125+- 所有开发必须在 worktree 中进行,不要在主仓库目录修改代码
126+
127+## 验收标准
128+
129+- AI 发送含 baa 指令的消息 → messages 表有记录 + 静态文件存在
130+- 指令执行完成 → executions 表有记录 + 静态文件存在
131+- 短结果(< 2000 字符)回送时包含完整内容 + artifact URL
132+- 长结果(> 2000 字符)回送时只有前 500 字符 + artifact URL
133+- `curl https://conductor.makefile.so/artifact/exec/{id}.txt` 返回完整执行结果
134+- sessions 表自动更新,`latest.txt` 包含最近活跃会话
135+- artifact 写入失败时不影响正常指令执行
136+
137+## 推荐验证命令
138+
139+- `cd /Users/george/code/baa-conductor-artifact-pipeline && pnpm build`
140+- `cd /Users/george/code/baa-conductor-artifact-pipeline && pnpm test`
141+- 实际跑一轮 BAA 指令闭环,检查 `state/artifacts/` 目录下是否生成了文件
142+- `curl https://conductor.makefile.so/artifact/session/latest.txt`
143+
144+## 执行记录
145+
146+> 以下内容由执行任务的 AI 填写,创建任务时留空。
147+
148+### 开始执行
149+
150+- 执行者:
151+- 开始时间:
152+- 状态变更:`待开始` → `进行中`
153+
154+### 完成摘要
155+
156+- 完成时间:
157+- 状态变更:`进行中` → `已完成`
158+- 修改了哪些文件:
159+- 核心实现思路:
160+- 跑了哪些测试:
161+
162+### 剩余风险
163+
+158,
-0
1@@ -0,0 +1,158 @@
2+# Task T-S041:Artifact 查询路由与会话索引
3+
4+## 状态
5+
6+- 当前状态:`待开始`
7+- 规模预估:`S`
8+- 依赖任务:`T-S039`
9+
10+## 直接给对话的提示词
11+
12+读 `/Users/george/code/baa-conductor/tasks/T-S041.md` 任务文档,完成开发任务。
13+
14+如需补背景,再读:
15+
16+- `/Users/george/code/baa-conductor/plans/ARTIFACT_STATIC_SERVICE.md`
17+
18+## 当前基线
19+
20+- 仓库:`/Users/george/code/baa-conductor`
21+- 分支基线:`main`(T-S039 合并后)
22+- 提交:`<T-S039 合并后的提交>`
23+
24+## 分支与 worktree(强制)
25+
26+每个任务必须使用独立的分支和 worktree,禁止直接在 main 上修改,禁止多个任务共用同一个 worktree。
27+
28+- 分支名:`feat/artifact-query-routes`
29+- worktree 路径:`/Users/george/code/baa-conductor-artifact-query-routes`
30+
31+开工步骤:
32+
33+1. `cd /Users/george/code/baa-conductor`
34+2. `git worktree add ../baa-conductor-artifact-query-routes -b feat/artifact-query-routes main`
35+3. `cd ../baa-conductor-artifact-query-routes`
36+4. 在这个 worktree 目录里开发,不要回到主仓库目录
37+
38+完成后合并步骤:
39+
40+1. 在 worktree 里提交所有变更
41+2. `cd /Users/george/code/baa-conductor`
42+3. `git merge feat/artifact-query-routes`
43+4. `git worktree remove ../baa-conductor-artifact-query-routes`
44+
45+合并冲突处理:
46+
47+1. 如果 `git merge` 报冲突,先 `git diff` 查看冲突文件
48+2. 手动解决冲突后 `git add` 冲突文件
49+3. `git merge --continue` 完成合并
50+4. 不要用 `git merge --abort` 然后 force 覆盖
51+
52+## 目标
53+
54+在 conductor HTTP server 上新增消息、执行记录和会话的查询路由,供管理用途和内部调用。
55+
56+## 背景
57+
58+T-S039 建了数据库,T-S040 接入了写入。但目前只能通过静态文件访问单条记录,还缺少列表查询、筛选和分页能力。本任务补齐查询路由。
59+
60+## 涉及仓库
61+
62+- `/Users/george/code/baa-conductor`
63+
64+## 范围
65+
66+- 新增 6 个查询路由
67+- 支持分页和筛选
68+- 注册到 `/describe` 和 `/v1/capabilities`
69+
70+## 允许修改的目录
71+
72+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/local-api.ts` (加路由)
73+- `/Users/george/code/baa-conductor/packages/artifact-db/` (如需补查询方法)
74+
75+## 尽量不要修改
76+
77+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/` (T-S040 的范围)
78+- `/Users/george/code/baa-conductor/plugins/`
79+- `/Users/george/code/baa-conductor/packages/db/`
80+
81+## 必须完成
82+
83+### 1. 消息查询路由
84+
85+- `GET /v1/messages` — 消息列表
86+ - 查询参数:`platform`、`conversation_id`、`limit`(默认 50)、`offset`(默认 0)
87+ - 按 `observed_at` 倒序
88+ - 返回 JSON 数组,每条包含 id, platform, conversation_id, role, summary, observed_at, artifact_url
89+- `GET /v1/messages/{id}` — 单条消息详情
90+ - 返回完整 JSON(含 raw_text)
91+
92+### 2. 执行记录查询路由
93+
94+- `GET /v1/executions` — 执行记录列表
95+ - 查询参数:`message_id`、`target`、`tool`、`limit`(默认 50)、`offset`(默认 0)
96+ - 按 `executed_at` 倒序
97+ - 返回 JSON 数组,每条包含 instruction_id, message_id, target, tool, result_ok, result_summary, executed_at, artifact_url
98+- `GET /v1/executions/{id}` — 单条执行详情
99+ - 返回完整 JSON(含 result_data)
100+
101+### 3. 会话查询路由
102+
103+- `GET /v1/sessions` — 会话索引
104+ - 查询参数:`platform`、`limit`(默认 20)、`offset`(默认 0)
105+ - 按 `last_activity_at` 倒序
106+- `GET /v1/sessions/latest` — 最近活跃会话
107+ - 返回最近 10 个活跃 session + 每个 session 的最近消息和执行 URL
108+
109+### 4. 注册到 describe 和 capabilities
110+
111+- 所有新路由在 `/describe/business` 中可发现
112+- 在 `/v1/capabilities` 中注册为 `kind: "read"`
113+
114+## 需要特别注意
115+
116+- 这些路由是只读查询,不需要 auth token
117+- 返回的 artifact_url 必须是 exact URL(包含完整域名和路径)
118+- `publicBaseUrl` 从 conductor 配置中获取
119+- 列表查询不返回 raw_text / result_data 完整内容(太大),只返回 summary + artifact_url
120+- 所有开发必须在 worktree 中进行,不要在主仓库目录修改代码
121+
122+## 验收标准
123+
124+- `curl http://100.71.210.78:4317/v1/messages` 返回 JSON 数组
125+- `curl http://100.71.210.78:4317/v1/messages?platform=claude&limit=10` 筛选正常
126+- `curl http://100.71.210.78:4317/v1/messages/{id}` 返回完整消息
127+- `curl http://100.71.210.78:4317/v1/executions` 返回 JSON 数组
128+- `curl http://100.71.210.78:4317/v1/sessions/latest` 返回最近会话索引
129+- `/describe/business` 包含新路由
130+- `/v1/capabilities` 包含新路由
131+
132+## 推荐验证命令
133+
134+- `cd /Users/george/code/baa-conductor-artifact-query-routes && pnpm build`
135+- `cd /Users/george/code/baa-conductor-artifact-query-routes && pnpm test`
136+- `curl http://100.71.210.78:4317/v1/messages | jq .`
137+- `curl http://100.71.210.78:4317/v1/sessions/latest | jq .`
138+- `curl http://100.71.210.78:4317/describe/business | jq .`
139+
140+## 执行记录
141+
142+> 以下内容由执行任务的 AI 填写,创建任务时留空。
143+
144+### 开始执行
145+
146+- 执行者:
147+- 开始时间:
148+- 状态变更:`待开始` → `进行中`
149+
150+### 完成摘要
151+
152+- 完成时间:
153+- 状态变更:`进行中` → `已完成`
154+- 修改了哪些文件:
155+- 核心实现思路:
156+- 跑了哪些测试:
157+
158+### 剩余风险
159+
+184,
-0
1@@ -0,0 +1,184 @@
2+# Task T-S042:D1 异步适配器与同步队列
3+
4+## 状态
5+
6+- 当前状态:`待开始`
7+- 规模预估:`M`
8+- 依赖任务:`T-S039`(需要表结构,但代码可并行开发)
9+
10+## 直接给对话的提示词
11+
12+读 `/Users/george/code/baa-conductor/tasks/T-S042.md` 任务文档,完成开发任务。
13+
14+如需补背景,再读:
15+
16+- `/Users/george/code/baa-conductor/plans/ARTIFACT_STATIC_SERVICE.md`
17+- `/Users/george/code/baa-old-files/baa/baa-server/lib/d1-client.js`(旧版 D1 适配器参考)
18+
19+## 当前基线
20+
21+- 仓库:`/Users/george/code/baa-conductor`
22+- 分支基线:`main`
23+- 提交:`6ea34e2`
24+
25+## 分支与 worktree(强制)
26+
27+每个任务必须使用独立的分支和 worktree,禁止直接在 main 上修改,禁止多个任务共用同一个 worktree。
28+
29+- 分支名:`feat/d1-async-adapter`
30+- worktree 路径:`/Users/george/code/baa-conductor-d1-async-adapter`
31+
32+开工步骤:
33+
34+1. `cd /Users/george/code/baa-conductor`
35+2. `git worktree add ../baa-conductor-d1-async-adapter -b feat/d1-async-adapter main`
36+3. `cd ../baa-conductor-d1-async-adapter`
37+4. 在这个 worktree 目录里开发,不要回到主仓库目录
38+
39+完成后合并步骤:
40+
41+1. 在 worktree 里提交所有变更
42+2. `cd /Users/george/code/baa-conductor`
43+3. `git merge feat/d1-async-adapter`
44+4. `git worktree remove ../baa-conductor-d1-async-adapter`
45+
46+合并冲突处理:
47+
48+1. 如果 `git merge` 报冲突,先 `git diff` 查看冲突文件
49+2. 手动解决冲突后 `git add` 冲突文件
50+3. `git merge --continue` 完成合并
51+4. 不要用 `git merge --abort` 然后 force 覆盖
52+
53+## 目标
54+
55+实现 TypeScript async 版本的 Cloudflare D1 适配器,以及本地 SQLite → D1 的异步同步队列。新建 D1 数据库,不复用旧版。
56+
57+## 背景
58+
59+旧版 baa-server 用 curl 同步调 D1 API,conductor 是 TypeScript 需要 async 版本。D1 作为分布式备份和跨设备访问层,本地 SQLite 先写不阻塞,D1 后台异步推送。
60+
61+## 涉及仓库
62+
63+- `/Users/george/code/baa-conductor`
64+- `/Users/george/code/baa-old-files/baa/baa-server/lib/d1-client.js`(只读参考)
65+
66+## 范围
67+
68+- TypeScript async D1 客户端
69+- 同步队列表(本地 SQLite)
70+- 后台同步 worker
71+- 环境变量配置
72+
73+## 推荐实现边界
74+
75+建议新增:
76+
77+- `packages/d1-client/` — 新 package
78+ - `src/client.ts` — async D1 HTTP API 客户端
79+ - `src/sync-queue.ts` — 同步队列管理
80+ - `src/sync-worker.ts` — 后台同步 worker
81+ - `src/types.ts` — 类型定义
82+
83+## 允许修改的目录
84+
85+- `/Users/george/code/baa-conductor/packages/` (新建 d1-client)
86+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/index.ts` (启动 sync worker)
87+
88+## 尽量不要修改
89+
90+- `/Users/george/code/baa-conductor/packages/db/`
91+- `/Users/george/code/baa-conductor/packages/artifact-db/` (T-S039 的范围)
92+- `/Users/george/code/baa-conductor/plugins/`
93+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/instructions/`
94+
95+## 必须完成
96+
97+### 1. D1 async 客户端
98+
99+- 参考旧版 `/Users/george/code/baa-old-files/baa/baa-server/lib/d1-client.js`
100+- 使用 `fetch`(不用 curl)调 Cloudflare D1 REST API
101+- 端点:`https://api.cloudflare.com/client/v4/accounts/{accountId}/d1/database/{databaseId}/query`
102+- 方法:`exec(sql)`, `prepare(sql).run(...params)`, `prepare(sql).get(...params)`, `prepare(sql).all(...params)`
103+- 所有方法返回 Promise
104+- 环境变量:`D1_DATABASE_ID`、`D1_ACCOUNT_ID`、`CLOUDFLARE_API_TOKEN`
105+- D1 未配置时,客户端返回 null(不报错),由调用方判断
106+
107+### 2. 同步队列
108+
109+- 本地 SQLite 新增 `d1_sync_queue` 表:
110+ ```sql
111+ CREATE TABLE IF NOT EXISTS d1_sync_queue (
112+ id INTEGER PRIMARY KEY AUTOINCREMENT,
113+ table_name TEXT NOT NULL,
114+ record_id TEXT NOT NULL,
115+ operation TEXT NOT NULL, -- 'insert' | 'update' | 'delete'
116+ payload TEXT NOT NULL, -- JSON
117+ created_at INTEGER NOT NULL,
118+ attempts INTEGER NOT NULL DEFAULT 0,
119+ last_attempt_at INTEGER,
120+ status TEXT NOT NULL DEFAULT 'pending' -- 'pending' | 'synced' | 'failed'
121+ );
122+ ```
123+- 写入本地 artifact DB 后,自动往 sync_queue 插入一条待同步记录
124+- 提供 `enqueueSyncRecord()` 和 `dequeuePendingSyncRecords()` 方法
125+
126+### 3. 后台同步 worker
127+
128+- conductor 启动时启动 sync worker
129+- 定时扫描 `d1_sync_queue`,取 pending 记录批量推送到 D1
130+- 成功后标记 `status = 'synced'`
131+- 失败后增加 `attempts`,指数退避重试(1s → 2s → 4s → ... 最大 5 分钟)
132+- 连续失败 10 次后标记 `status = 'failed'`,不再重试
133+- D1 未配置时,worker 不启动(静默跳过)
134+- worker 异常不影响 conductor 主流程
135+
136+### 4. 建 D1 远程数据库
137+
138+- 提供建库脚本或说明文档
139+- 表结构与本地 artifact DB 完全一致(messages、executions、sessions)
140+- 不复用旧版 D1 数据库
141+
142+## 需要特别注意
143+
144+- D1 同步是可选的,D1 不可用时本地功能完全不受影响
145+- sync worker 不能阻塞 conductor 主线程
146+- 同步队列表放在本地 artifact.db 中(与 messages/executions 同库)
147+- 旧版 D1Client 用的是 `execSync`(curl),新版必须用 async fetch
148+- 所有开发必须在 worktree 中进行,不要在主仓库目录修改代码
149+
150+## 验收标准
151+
152+- D1 环境变量未设置时,conductor 正常启动,sync worker 不启动
153+- D1 环境变量设置后,sync worker 启动,定时扫描队列
154+- 本地写入 message 后,sync_queue 中出现 pending 记录
155+- sync worker 成功推送后,记录标记为 synced
156+- D1 不可达时,记录保持 pending,指数退避重试
157+- 连续失败超限后,记录标记为 failed
158+- sync worker 异常不影响 conductor 主进程
159+
160+## 推荐验证命令
161+
162+- `cd /Users/george/code/baa-conductor-d1-async-adapter && pnpm build`
163+- `cd /Users/george/code/baa-conductor-d1-async-adapter && pnpm test`
164+- 设置 D1 环境变量后启动 conductor,观察 sync worker 日志
165+
166+## 执行记录
167+
168+> 以下内容由执行任务的 AI 填写,创建任务时留空。
169+
170+### 开始执行
171+
172+- 执行者:
173+- 开始时间:
174+- 状态变更:`待开始` → `进行中`
175+
176+### 完成摘要
177+
178+- 完成时间:
179+- 状态变更:`进行中` → `已完成`
180+- 修改了哪些文件:
181+- 核心实现思路:
182+- 跑了哪些测试:
183+
184+### 剩余风险
185+
+11,
-6
1@@ -33,13 +33,18 @@
2
3 ## 当前活跃任务与优先级
4
5-### P0(下一阶段主线)
6+### P0(下一阶段主线:Artifact 静态服务)
7
8-- **Artifact 静态服务**:[`../plans/ARTIFACT_STATIC_SERVICE.md`](../plans/ARTIFACT_STATIC_SERVICE.md)
9- - 所有消息和执行结果全量入库 + 生成静态 URL
10- - AI 通过 fetch URL 获取完整内容
11- - 跨会话接续
12- - 分支:`feat/artifact-static-service`(待创建)
13+方案文档:[`../plans/ARTIFACT_STATIC_SERVICE.md`](../plans/ARTIFACT_STATIC_SERVICE.md)
14+
15+| 任务 | 标题 | 规模 | 依赖 | 状态 |
16+|---|---|---|---|---|
17+| [`T-S039`](./T-S039.md) | Artifact 基础层(DB + 静态文件 + HTTP 路由) | M | 无 | 待开始 |
18+| [`T-S040`](./T-S040.md) | Artifact 接入指令执行主链路 | M | T-S039 | 待开始 |
19+| [`T-S041`](./T-S041.md) | Artifact 查询路由与会话索引 | S | T-S039 | 待开始 |
20+| [`T-S042`](./T-S042.md) | D1 异步适配器与同步队列 | M | T-S039(可并行开发) | 待开始 |
21+
22+执行顺序:T-S039 先行 → T-S040 和 T-S041 可并行 → T-S042 独立
23
24 ### P1(并行优化)
25