From c856d612ea5a6e06a91fb21d534da31ffa587140 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Mon, 18 May 2026 08:24:10 +0800 Subject: [PATCH] auto-sync: 2026-05-18 08:24:10 --- docs/design/v2.7-subtask-model.md | 326 ++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 docs/design/v2.7-subtask-model.md diff --git a/docs/design/v2.7-subtask-model.md b/docs/design/v2.7-subtask-model.md new file mode 100644 index 0000000..6a4e817 --- /dev/null +++ b/docs/design/v2.7-subtask-model.md @@ -0,0 +1,326 @@ +# v2.7 数据模型重新设计:Project → Task → SubTask + +> 日期:2026-05-18 +> 版本:v1.0(基于 2026-05-18 08:13 ~ 08:21 讨论定稿) +> 作者:庞统 +> 状态:待确认 +> 前置:回滚 v2.7 Card 层(设计文档 + 代码) + +--- + +## 一、概念对齐 + +| 层级 | 语义 | 例子 | 谁创建 | 生命周期 | +|------|------|------|--------|---------| +| **Project** | 仓库/组织 | sanguo_quant_live、sanguo_vnpy | 系统(自动发现)+ 用户 | 长期 | +| **Task** | 用户的一条需求/意图/目标 | "动量策略v1"、"下载分钟线"、"v2.7开发" | 用户 / AI | 天~周 | +| **SubTask** | Agent 领走执行的原子动作 | 张飞编码、赵云备数据、司马懿评审 | AI(庞统分解)| 小时~天 | + +### 关键认知 + +1. **Task 是用户视角的最小单位**:用户说"帮我做动量策略v1",这就是一个 Task +2. **SubTask 是 Agent 视角的最小单位**:庞统把 Task 拆解后分发给各将军 +3. **SubTask 可以跨 Project**:姜维在 sanguo_vnpy 搭回测引擎,服务的是 sanguo_quant_live 的 Task +4. **SubTask ≈ Stage**:同一个 Task 的 SubTask 按执行顺序形成 Stage 链 +5. **Task 间有依赖**:策略编码依赖数据准备,实盘依赖模拟验证 + +--- + +## 二、回滚范围 + +### 回滚 Card 相关代码(开发目录) + +| 文件 | 操作 | +|------|------| +| `src/blackboard/models.py` | 删除 Card 相关代码(CARD_VALID_STATUSES 等 + Card dataclass) | +| `src/blackboard/db.py` | 删除 `_CARDS_SCHEMA`、`_migrate_v27()`、cards 表 DDL;tasks 表移除 `card_id`、`stage` 列 | +| `src/blackboard/operations.py` | 删除 CardOps 类(create_card / list_cards / fork_card 等) | +| `src/blackboard/queries.py` | 移除 card_id 过滤参数 | +| `src/api/card_routes.py` | **删除整个文件** | +| `src/api/mail_routes.py` | **删除整个文件**(Mail 后续重新设计) | +| `src/blackboard/registry.py` | 保留 ProjectRegistry(不涉及 Card) | +| `src/daemon/ticker.py` | 移除 per-card 扫描逻辑,恢复 v2.6 per-project 扫描 | +| `src/main.py` | 移除 card_routes、mail_routes 注册;移除 v2.7 迁移调用 | +| `tests/test_v27_cards.py` | **删除整个文件** | + +### 回滚设计文档 + +| 文件 | 操作 | +|------|------| +| `docs/design/v2.7-three-tier-hierarchy.md` | 归档到 `docs/design/archive/` | + +### 保留 + +| 文件/功能 | 原因 | +|-----------|------| +| `registry.db` + ProjectRegistry + 自动发现 | Project 管理需要 | +| per-project `blackboard.db` | 多项目隔离需要 | +| Project API 路由 | 前端项目选择器需要 | +| Product 方向备忘录 | 新增,记录未来方向 | + +--- + +## 三、新增:SubTask 层 + +### 3.1 数据模型 + +**SubTask 表**(加到 per-project blackboard.db): + +```sql +CREATE TABLE IF NOT EXISTS subtasks ( + id TEXT PRIMARY KEY, -- 自动生成(如 st-a1b2c3) + task_id TEXT NOT NULL REFERENCES tasks(id), -- 所属 Task + title TEXT NOT NULL, -- 如 "策略编码"、"数据清洗" + description TEXT DEFAULT '', + status TEXT NOT NULL DEFAULT 'pending' + CHECK (status IN ('pending','claimed','working','review','done','failed','blocked','cancelled')), + assignee TEXT, -- 执行 Agent(如 zhangfei-dev) + assigned_by TEXT, -- 分配者(通常是 pangtong-fujunshi) + stage TEXT DEFAULT NULL, -- 所属 Stage 标签(如 "research"、"coding") + stage_order INTEGER DEFAULT 0, -- Stage 内排序 + depends_on TEXT, -- JSON array of subtask ids(SubTask 间依赖) + output_summary TEXT DEFAULT NULL, -- 产出物摘要 + output_path TEXT DEFAULT NULL, -- 产出物路径 + parent_project TEXT DEFAULT NULL, -- 实际工作所在 Project(跨项目时用) + retry_count INTEGER NOT NULL DEFAULT 0, + max_retries INTEGER NOT NULL DEFAULT 2, + created_at TEXT NOT NULL DEFAULT (datetime('now')), + updated_at TEXT NOT NULL DEFAULT (datetime('now')), + started_at TEXT, + completed_at TEXT +); +CREATE INDEX IF NOT EXISTS idx_subtasks_task ON subtasks(task_id); +CREATE INDEX IF NOT EXISTS idx_subtasks_status ON subtasks(status); +CREATE INDEX IF NOT EXISTS idx_subtasks_assignee ON subtasks(assignee); +CREATE INDEX IF NOT EXISTS idx_subtasks_stage ON subtasks(task_id, stage); +``` + +### 3.2 Task 表变更 + +在现有 tasks 表基础上,新增字段: + +```sql +ALTER TABLE tasks ADD COLUMN stages_json TEXT DEFAULT '[]'; -- Stage 定义(AI 生成) +ALTER TABLE tasks ADD COLUMN plan_json TEXT DEFAULT NULL; -- 完整分解计划(庞统生成) +``` + +**`stages_json` 格式**: + +```json +[ + {"id": "research", "label": "因子研究", "order": 1}, + {"id": "data_prep", "label": "数据准备", "order": 2}, + {"id": "coding", "label": "策略编码", "order": 3}, + {"id": "backtest", "label": "历史回测", "order": 4}, + {"id": "optimize", "label": "参数优化", "order": 5} +] +``` + +**`plan_json` 格式**: + +```json +{ + "version": 1, + "created_by": "pangtong-fujunshi", + "created_at": "2026-05-18T08:00:00Z", + "stages": [...], + "subtasks": [ + { + "id": "st-001", + "title": "因子研究", + "assignee": "zhangfei-dev", + "stage": "research", + "depends_on": [], + "parent_project": null + }, + { + "id": "st-002", + "title": "分钟线数据下载", + "assignee": "zhaoyun-data", + "stage": "data_prep", + "depends_on": [], + "parent_project": null + }, + { + "id": "st-003", + "title": "策略编码", + "assignee": "zhangfei-dev", + "stage": "coding", + "depends_on": ["st-001", "st-002"], + "parent_project": null + }, + { + "id": "st-004", + "title": "回测引擎搭建", + "assignee": "jiangwei-infra", + "stage": "backtest", + "depends_on": [], + "parent_project": "sanguo_vnpy" + } + ] +} +``` + +### 3.3 跨项目 SubTask + +**`parent_project` 字段**: + +- `NULL`:SubTask 在当前 Project 内执行 +- `"sanguo_vnpy"`:SubTask 实际工作在另一个 Project 目录 + +跨项目 SubTask 的执行流程: +1. 庞统在 Task A(sanguo_quant_live)分解时,识别到需要回测引擎 +2. 创建 SubTask st-004,`parent_project=sanguo_vnpy` +3. Ticker 在 sanguo_vnpy 项目也扫描到这个 SubTask(通过 cross-project 查询) +4. 姜维在 sanguo_vnpy 执行完成后,结果写回 Task A 的 SubTask + +**注意**:跨项目执行是复杂场景,v2.7 先做数据模型支持(字段存在),执行逻辑后续迭代。 + +### 3.4 现有表关联 SubTask + +以下表新增 `subtask_id` 字段(可选,向后兼容): + +```sql +ALTER TABLE events ADD COLUMN subtask_id TEXT; +ALTER TABLE comments ADD COLUMN subtask_id TEXT; +ALTER TABLE outputs ADD COLUMN subtask_id TEXT; +ALTER TABLE task_attempts ADD COLUMN subtask_id TEXT; +``` + +这样 Events、Comments、Outputs 既可以关联到 Task 级别,也可以精确到 SubTask 级别。 + +--- + +## 四、Task 状态 = SubTask 状态聚合 + +Task 不独立维护复杂状态机,核心状态从 SubTask 推导(类似之前 Card 的聚合逻辑,但语义更自然): + +| Task 状态 | 推导规则 | +|-----------|---------| +| `pending` | 所有 SubTask 都是 pending,或无 SubTask | +| `working` | 有 SubTask 在 working | +| `review` | 有 SubTask 在 review | +| `done` | 所有 SubTask 都是 done | +| `failed` | 有 SubTask failed 且无 active SubTask | +| `blocked` | 有 SubTask blocked 且无 active SubTask | +| `cancelled` | 用户/AI 取消(手动设置) | + +**额外状态**(不属于聚合,手动设置): +- `planning`:庞统正在分解 Task(生成 plan_json) +- `challenging`:司马懿正在审核分解方案 + +--- + +## 五、API 路由 + +### 5.1 Task 级(已有,微调) + +``` +GET /api/projects/{pid}/tasks → Task 列表(含 SubTask 聚合状态) +POST /api/projects/{pid}/tasks → 创建 Task(用户需求) +GET /api/projects/{pid}/tasks/{tid} → Task 详情 + Stage 进度 +PATCH /api/projects/{pid}/tasks/{tid} → 更新 Task(如取消、改优先级) +DELETE /api/projects/{pid}/tasks/{tid} → 删除 Task +``` + +### 5.2 SubTask 级(新增) + +``` +GET /api/projects/{pid}/tasks/{tid}/subtasks → Task 下所有 SubTask(按 Stage 分组) +POST /api/projects/{pid}/tasks/{tid}/subtasks → 创建 SubTask(AI/手动) +GET /api/projects/{pid}/tasks/{tid}/subtasks/{stid} → SubTask 详情 +PATCH /api/projects/{pid}/tasks/{tid}/subtasks/{stid} → 更新 SubTask(状态、指派) +POST /api/projects/{pid}/tasks/{tid}/subtasks/{stid}/status → 更新状态(Agent 回调) +POST /api/projects/{pid}/tasks/{tid}/subtasks/{stid}/outputs → 提交产出 +``` + +### 5.3 便利路由 + +``` +GET /api/projects/{pid}/tasks/{tid}/progress → Stage 进度条数据 +GET /api/projects/{pid}/subtasks → 项目级所有 SubTask(跨 Task 查询) +``` + +### 5.4 向后兼容 + +- 旧路由 `/api/projects/{pid}/tasks` 保留 +- 不传 SubTask 相关参数时行为不变 +- Task 的 status 仍然可用(聚合推导) + +--- + +## 六、Ticker 变更 + +### 6.1 扫描逻辑 + +```python +for project in registry.list_projects(status='active'): + db_path = data_root / project.id / "blackboard.db" + tasks = queries.tasks_by_status(db_path, ['pending', 'working', 'planning']) + for task in tasks: + # 1. 如果 Task 在 planning → 触发庞统分解 + if task.status == 'planning': + dispatch_planning(task) + continue + # 2. 扫描 Task 下 pending 的 SubTask + pending = queries.pending_subtasks(db_path, task.id) + for subtask in pending: + if deps_satisfied(subtask): + dispatch_subtask(subtask) + # 3. 聚合刷新 Task 状态 + refresh_task_status(db_path, task.id) +``` + +### 6.2 调度粒度 + +- **调度单位**:SubTask(不是 Task) +- **状态聚合**:每次 tick 刷新 Task 的聚合状态 +- **max_dispatch_per_tick**:全局限制(恢复 v2.6 语义) + +--- + +## 七、前端改动(最小) + +### 7.1 不改的 + +- 整体布局不变(Tab 栏 + 内容区) +- 项目选择器保持下拉菜单 +- EdictBoard(Task 看板)基本不变 + +### 7.2 改的 + +1. **Task 详情弹窗(TaskModal.tsx)**: + - 新增 Stage 进度条(从 stages_json 读取) + - SubTask 列表(按 Stage 分组) + - 每个 SubTask 显示:标题、Agent、状态、产出 + +2. **Task 看板卡片**: + - 加 Stage 进度指示器(小进度条) + +3. **Mail Tab**(后续独立实现): + - 新增 Tab,列表展示 Sanguo Mail + +### 7.3 暂不做的 + +- 独立的 SubTask 看板/管理页面 +- 跨 Project 的 Product 视图 +- Card 看板 + +--- + +## 八、实施计划 + +| 序号 | 任务 | 预计 | +|------|------|------| +| 1 | 回滚 Card 层(代码 + 设计文档归档) | 2h | +| 2 | 新增 SubTask 表 + models + operations | 3h | +| 3 | Task 表加 stages_json/plan_json + 聚合状态 | 2h | +| 4 | SubTask API 路由 | 2h | +| 5 | Ticker 适配(per-SubTask 调度 + 状态聚合) | 2h | +| 6 | 前端 Task 详情弹窗改造(Stage 进度 + SubTask 列表) | 3h | +| 7 | 测试 + 司马懿评审 | 2h | +| **合计** | | **~16h** | + +### 优先级 + +先回滚(1)→ 再建 SubTask(2-5)→ 前端(6)→ 评审测试(7)