# 任务/子任务数据关系与存储梳理

本文梳理 EvoFlow 当前「主任务 + 子任务 + 子任务实时流 + 子任务产出数据」的数据模型、写入/读取链路、落盘目录格式，以及各层之间的关系。

## 1. 范围与结论

- 面向对象：`main task`、`subtask`、`subtask runtime stream`、`task memory`。
- 对外语义：以 `task/subtask` 为中心（API 响应不强调 project 概念）。
- 当前唯一展示真值策略：
  - 状态：以 `projects.tasks[].subtasks[]` 为准。
  - 内容摘要：以 `task_memory.output_summary` 为准。
  - 读取接口（如 `/api/task-memory/tasks/{subtaskId}`）会互补并回填落盘。

## 2. 目录与文件格式（Host 侧）

根目录：`{base_dir}`（见 `Paths.base_dir`，默认 `$HOME/.evoflow`）

- 任务主存储（结构化任务树）
  - 目录：`{base_dir}/projects/`
  - 文件：`project_{project_id}.json`
  - 索引：`{base_dir}/projects/index.json`
- 任务记忆存储（按 task/subtask 粒度）
  - 目录：`{base_dir}/task_memory/{project_id}/agents/{agent_id}/`
  - 文件：`{task_id_or_subtask_id}.json`
- 线程协作状态（线程级执行阶段）
  - 文件：`{base_dir}/threads/{thread_id}/collab_state.json`
- 任务流快照日志（调试/回放引导）
  - 目录：`{base_dir}/task_stream_logs/`
  - 文件：`{main_task_id}.jsonl`

> 说明：内部仍用 `project_id` 做物理分桶，但 API 与 UI 展示可保持 task 语义。

## 3. 四类核心数据

### 3.1 主任务/子任务行（projects）

存储在 `project_{id}.json`：

- 主任务：`tasks[]` 条目
- 子任务：`tasks[].subtasks[]` 条目
- 典型字段：
  - `id/name/status/progress`
  - 子任务补充：`assigned_to/result/error/observed_tool_calls/output_summary`

用途：

- 任务状态主真值（尤其是终态：`completed/failed/cancelled/timed_out`）
- `/api/tasks/{task_id}/subtasks` 直接读取这一层

### 3.2 任务记忆（task_memory）

文件：`task_memory/{project_id}/agents/{agent_id}/{task_or_subtask_id}.json`

- 典型字段：`status/progress/current_step/output_summary/facts`
- 主任务可做聚合（由子任务 memory 汇总）

用途：

- 子任务详情弹窗、总结摘要、facts 语义层数据
- `/api/task-memory/tasks/{id}` 读取这一层（并做互补）

### 3.3 线程协作态（collab_state）

文件：`threads/{thread_id}/collab_state.json`

- 典型字段：`collab_phase/bound_task_id/sidebar_supervisor_steps`
- 仅表示线程执行阶段与绑定关系，不承载子任务终态真值

用途：

- 前端是否需要挂 task-stream
- 侧栏时间线恢复

### 3.4 实时流与快照日志

- 实时：
  - `task_tool` / `claude_session` 产生 `task_started/task_running/task_completed/...`
  - 经 `broadcast_collab_task_event(...)` 推到网关 SSE
- 快照：
  - `/api/collab/threads/{thread_id}/task-stream` 周期输出 `task_progress`（含 `snapshot + memory`）
  - 同步写 `task_stream_logs/{main_task_id}.jsonl` 供回放引导

## 4. 写入链路（统一后）

已统一子任务写模型：`persist_subtask_runtime_snapshot(...)`

- 写入目标：
  - `projects.subtasks[]`（状态/进度/result/error/observed_*）
  - `task_memory`（status/progress/output_summary/current_step）
- 调用方：
  - `task_tool`（运行中增量 + 终态）
  - `supervisor -> claude_session` 路径（失败/完成）

额外终态语义：

- 子任务终态后会触发根任务进度 rollup（`rollup_root_task_progress_from_subtasks`）
- 主任务聚合 memory 会在 supervisor 收敛路径更新

## 5. 读取链路（对外）

### 5.1 子任务列表

- API：`GET /api/tasks/{task_id}/subtasks`
- 数据源：`projects.subtasks[]`（状态主真值）

### 5.2 子任务记忆

- API：`GET /api/task-memory/tasks/{subtask_id}`
- 主数据源：`task_memory`
- 互补逻辑：
  - 若 memory 空/滞后，回填 subtask 行的 `status/progress/result/error`
  - 回填后立刻 `save_task_memory`（写回落盘，避免每次临时修补）

### 5.3 线程任务流

- API：`GET /api/collab/threads/{thread_id}/task-stream`（SSE）
- 数据源：
  - `build_task_progress_snapshot(...)`（projects + memory 聚合）
  - 网关事件广播（`task:running` 等实时事件）

## 6. 关系图（示意）

```mermaid
flowchart TD
  A[task_tool / claude_session] --> B[persist_subtask_runtime_snapshot]
  B --> C[projects/project_*.json<br/>tasks[].subtasks[]]
  B --> D[task_memory/{project}/agents/{agent}/{subtask}.json]

  C --> E[/api/tasks/{task}/subtasks]
  D --> F[/api/task-memory/tasks/{subtask}]
  C --> G[build_task_progress_snapshot]
  D --> G
  G --> H[/api/collab/threads/{thread}/task-stream]
  H --> I[ChatApp + SessionSidebar]

  J[broadcast_collab_task_event] --> K[/api/events/internal/broadcast]
  K --> H

  L[threads/{thread}/collab_state.json] --> H
  L --> I
```

## 7. 一致性策略与巡检

- 轻量巡检函数：`reconcile_subtask_memory_consistency(...)`
  - 比对 `subtask.status/progress/output_summary` 与 `task_memory` 差异
  - 发现漂移时通过统一入口修复
- 触发点：
  - 当前在 `build_task_progress_snapshot(...)` 中做 best-effort 修复

## 8. 目前仍需注意的边界

- 物理存储分桶仍按 `project_id`，属于内部实现细节（对外已可 task 语义化）。
- 如果某些历史路径仍直接改 `projects` 或直接改 `task_memory`，可能短时漂移；巡检会在快照路径收敛。
- `collab_phase` 是线程执行态，不应作为子任务终态判断依据。

## 9. 代码定位（便于继续演进）

- 路径定义：`backend/packages/harness/evoflow/config/paths.py`
- 主存储与统一写入：`backend/packages/harness/evoflow/collab/storage.py`
- 线程快照聚合：`backend/packages/harness/evoflow/collab/task_progress_snapshot.py`
- 线程协作态：`backend/packages/harness/evoflow/collab/thread_collab.py`
- task-memory API：`backend/app/gateway/routers/task_memory.py`
- task-stream SSE：`backend/app/gateway/routers/collab.py`
- 子任务执行入口：
  - `backend/packages/harness/evoflow/tools/builtins/task_tool.py`
  - `backend/packages/harness/evoflow/tools/builtins/supervisor/execution.py`
