# v2.8 + M3 完整设计：状态增强 + 前端易用性 + Checkpoint + Artifact

> 状态: ✅ 评审通过（Mail #303/#304/#305），待用户确认  
> 日期: 2026-05-18  
> 作者: 庞统  
> 评审: 司马懿  

---

## 📋 概述

### 背景
v2.7 已完成 Card 回滚、SubTask 聚合、Mail Tab。本设计覆盖 v2.8 状态增强 + 前端易用性 + M3 Checkpoint/Artifact。

### 问题
1. v2.7 状态机缺少 `paused`、`escalated`、`waiting_human`（v1.0 已有）
2. 前端缺少已取消/已归档筛选，无法管理已完成任务
3. 卡片没有快捷操作按钮，每次操作需点进 Modal
4. 项目切换在 header，不在筛选栏
5. Checkpoint 人工干预和成果物展示是 M3 核心功能，依赖 `waiting_human` 状态

### 目标
1. 补齐 3 个缺失状态
2. 归档机制 + 前端两行筛选栏 + 卡片快捷按钮
3. 项目下拉移入筛选栏 + 跨项目聚合
4. Checkpoint 三种类型 + Artifact 成果物面板
5. 新建军令 title 可选

---

## 一、状态机增强

### 1.1 新增状态定义

| 状态 | 中文 | 颜色 | 类型 | 说明 |
|------|------|------|------|------|
| `paused` | 已暂停 | `#818cf8` 紫 | 手动 | 用户主动暂停，不参与聚合、不超时 |
| `escalated` | 已升级 | `#ff5270` 红 | 手动 | Agent 升级求助，需人工介入 |
| `waiting_human` | 等待人工 | `#f59e0b` 橙 | 中间态 | Checkpoint 等人工确认后推进 |

### 1.2 完整状态转换表（共 11 个状态）

```
pending:       [claimed, cancelled]
claimed:       [working, paused, pending, cancelled]
working:       [review, blocked, failed, paused, escalated, waiting_human, cancelled]
paused:        [working, cancelled]
review:        [done, pending, failed, escalated, waiting_human, cancelled]
blocked:       [pending, escalated, cancelled]
failed:        [pending, escalated, cancelled]
escalated:     [working, pending, cancelled]
waiting_human: [working, done, cancelled]
done:          []
cancelled:     []
```

### 1.3 各状态设计细节

#### paused（已暂停）
- **触发**：用户点暂停按钮（卡片右上角 ⏸）
- **恢复**：用户点 ▶ 继续 → 回到 working
- **调度**：Ticker 跳过（不 claim、不超时回收）
- **聚合**：不参与父 Task 聚合（同 cancelled）
- **超时**：无，无限等待

#### escalated（已升级）
- **触发**：Agent 遇到无法处理的问题，通过 status API 设置
- **恢复**：用户介入后手动恢复到 working 或 pending
- **调度**：Ticker 跳过
- **聚合**：视同 working 参与（表示活跃但需关注）
- **字段迁移**：废弃 `task.escalated` 布尔字段判断，改用 `task.status === 'escalated'`。保留 DB 字段做向后兼容
- **旧数据处理**：旧 DB 中 `escalated=1` 但 `status=working` 的任务，按 working 继续调度，可接受
- **UI**：卡片红色高亮 + ⚠️ 图标

#### waiting_human（等待人工）
- **触发**：Agent 执行到 Checkpoint，写 checkpoint 数据 + 设置此状态
- **推进**：人工 approve → working/done；reject → working（带回退信息）
- **调度**：Ticker 跳过（等人工不等超时）
- **聚合**：视同 working 参与
- **UI**：卡片橙色高亮 + 🔔 图标 + Checkpoint 面板入口

### 1.4 聚合规则

```
父 Task 聚合优先级（高→低）：
  escalated > waiting_human > review > working/claimed > pending > failed > blocked

不参与聚合：
  paused, cancelled（手动/被动状态）

全部 done → done
```

### 1.5 Ticker 调度规则

| 状态 | claim | 超时回收 | review 调度 |
|------|-------|---------|------------|
| pending | ✅ | - | - |
| claimed | - | ✅（超时→pending） | - |
| working | - | ✅（超时→failed） | - |
| review | - | - | ✅ |
| paused | ❌ | ❌ | ❌ |
| escalated | ❌ | ❌ | ❌ |
| waiting_human | ❌ | ❌ | ❌ |
| done | 终态 | | |
| failed | ❌ | | |
| blocked | ❌ | | |
| cancelled | 终态 | | |

---

## 二、归档机制

### 2.1 后端

- `tasks` 表新增：`archived INTEGER DEFAULT 0`、`archived_at TEXT`
- `Task` dataclass 新增：`archived: int = 0`、`archived_at: Optional[str] = None`
- `Blackboard` 新增方法：
  - `archive_task(task_id)` → archived=1
  - `unarchive_task(task_id)` → archived=0
  - `archive_all_done()` → 批量归档当前项目 done + cancelled 的任务（单项目操作）
- API：
  - `POST /api/projects/{pid}/tasks/{tid}/archive` — 归档/取消归档
  - `POST /api/projects/{pid}/tasks/archive-done` — 一键归档
- 列表查询 API 默认 `?archived=0`

### 2.2 前端

- 第 1 行：活跃/归档/全部 切换
- 一键归档按钮（有可归档任务时显示）
- 卡片上 done/cancelled 显示归档按钮

### 2.3 Schema 迁移（db.py）

```sql
-- 新增字段
ALTER TABLE tasks ADD COLUMN archived INTEGER DEFAULT 0;
ALTER TABLE tasks ADD COLUMN archived_at TEXT;

-- 更新 CHECK 约束（重建 tasks 表或用新连接 pragma）
-- 完整 CHECK: status IN ('pending','claimed','working','review','done','failed','blocked','cancelled','paused','escalated','waiting_human')
```

---

## 三、前端易用性改造

### 3.1 筛选栏两行布局（仿 v1.0）

**第 1 行（项目 + 归档控制）**：
```
[📦 项目▾] [活跃] [归档] [全部]    活跃12 · 归档5 · 共17    [📦 一键归档]
```
- 项目下拉：`📋 全部任务`（""）→ `📁 一般任务`（"projects"）→ 动态项目列表
- 全部任务：聚合所有项目的 tasks

**第 2 行（状态筛选 + 搜索）**：
```
[📋全部] [📋待认领] [👤已认领] [⚔️执行中] [🔍审查中] [⏸已暂停] [⚠️已升级] [🔔等人工] [✅已完成] [❌失败] [🚧阻塞] [🚫已取消]    🔍[搜索框]
```

### 3.2 卡片改造

**右上角状态图标**：
- working/claimed → `⏸` 暂停按钮
- paused → `▶` 恢复按钮
- escalated → `⚠️` 图标
- waiting_human → `🔔` 图标

**卡片按钮（最多 3 个）**：

| 状态 | 卡片按钮 |
|------|---------|
| pending | `👤 认领` `🚫` |
| claimed | `⚔️ 开始` `🚫` |
| working | `🔍 提审` `⏸` `🚫` |
| paused | `▶ 继续` `🚫` |
| review | `✅ 通过` `🚫` |
| escalated | `▶ 继续` `🚫` |
| waiting_human | `✅ 确认` `🚫` |
| done | `📦 归档` |
| failed | `🔄 重试` |
| blocked | `🔄 解除` `🚫` |
| cancelled | `📦 归档` |

**Modal 完整按钮（最多 4 个）**：

| 状态 | Modal 按钮 |
|------|-----------|
| pending | `👤 认领` `🚫 取消` |
| claimed | `⚔️ 开始` `⏸ 暂停` `🚫 取消` |
| working | `🔍 提审` `⏸ 暂停` `⚠️ 升级` `🚫 取消` |
| paused | `▶ 继续` `🚫 取消` |
| review | `✅ 通过` `🔄 打回` `❌ 驳回` `⚠️ 升级` |
| escalated | `▶ 继续` `🔄 重置` `🚫 取消` |
| waiting_human | `✅ 确认` `❌ 驳回` |
| done | `📦 归档` |
| failed | `🔄 重试` `⚠️ 升级` `🚫 取消` |
| blocked | `🔄 解除` `⚠️ 升级` `🚫 取消` |
| cancelled | `📦 归档` |

- 点击标题区域打开 Modal
- 动作按钮直接调 API + toast 反馈

### 3.3 新建军令 title 自动生成

- 前端 title 可选，placeholder "不填将自动生成"
- 后端 title 为空时：description 前 30 字 + "…"

---

## 四、Checkpoint 机制（M3）

### 4.1 概念

Agent 执行到需要人工确认的节点时，创建 Checkpoint 并设置 `waiting_human` 状态。用户在前端看到 Checkpoint 面板，审核后任务继续。

### 4.2 三种 Checkpoint 类型

| 类型 | 图标 | 主色 | 场景 | 核心交互 |
|------|------|------|------|----------|
| **验证** | 🔍 | `#6a9eff` 蓝 | 产出物确认、效果验收 | 自动核验 + 人工核验 + 双按钮审批 |
| **决策** | 🎯 | `#818cf8` 紫 | 多方案定夺、技术选型 | 三方案并排 + 利弊 + 推荐 + 确认 |
| **执行** | 🔧 | `#f59e0b` 橙 | 人工操作、环境变更 | 分步打勾 + 命令行 + 进度条 |

### 4.3 approve/reject 状态推进规则

| Checkpoint 类型 | approve → | reject → |
|----------------|-----------|----------|
| verify | **done** | working（带回退信息） |
| decision | working（Agent 按选定方案继续） | working（带驳回信息） |
| action | working（Agent 继续后续步骤） | working（带失败信息） |

**统一规则**：verify approve → done（验证通过即完成），其余 approve → working。reject 一律 → working。

### 4.4 后端数据模型

#### checkpoints 表

```sql
CREATE TABLE checkpoints (
    id TEXT PRIMARY KEY,
    task_id TEXT NOT NULL,
    type TEXT NOT NULL CHECK (type IN ('verify', 'decision', 'action')),
    title TEXT NOT NULL,
    description TEXT,
    status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'rejected')),
    payload TEXT NOT NULL,          -- JSON，含 version 字段
    created_at TEXT NOT NULL DEFAULT (datetime('now')),
    resolved_at TEXT,
    resolved_by TEXT,
    resolve_note TEXT,
    FOREIGN KEY (task_id) REFERENCES tasks(id)
);
```

#### payload 结构（version: 1）

**验证（verify）**：
```json
{
  "version": 1,
  "auto_checks": [{"label": "测试通过", "passed": true}],
  "human_steps": ["确认代码风格", "确认功能正确"],
  "preview_url": "http://..."
}
```

**决策（decision）**：
```json
{
  "version": 1,
  "options": [
    {"id": "opt1", "label": "方案A", "desc": "...", "pros": ["..."], "cons": ["..."], "recommended": true},
    {"id": "opt2", "label": "方案B", "desc": "...", "pros": ["..."], "cons": ["..."]},
    {"id": "opt3", "label": "方案C", "desc": "...", "pros": ["..."], "cons": ["..."]}
  ]
}
```

**执行（action）**：
```json
{
  "version": 1,
  "steps": [
    {"id": "s1", "desc": "备份数据库", "command": "mysqldump ..."},
    {"id": "s2", "desc": "执行迁移", "command": "python migrate.py"}
  ],
  "verify_command": "python check.py"
}
```

### 4.5 API

```
GET    /api/projects/{pid}/tasks/{tid}/checkpoints               — 列出 task 的所有 checkpoint
POST   /api/projects/{pid}/tasks/{tid}/checkpoints               — Agent 创建 checkpoint
POST   /api/projects/{pid}/tasks/{tid}/checkpoints/{cid}/approve — 用户通过
POST   /api/projects/{pid}/tasks/{tid}/checkpoints/{cid}/reject                    — 用户驳回
```

approve/reject 时后端自动将 task 从 `waiting_human` 推进：
- approve: verify → done, decision/action → working
- reject: 一律 → working

### 4.6 Agent 触发流程

```
1. Agent 执行到需要人工确认的节点
2. Agent 调 POST /checkpoints 创建 checkpoint（type + payload）
3. Agent 调 POST /tasks/{id}/status 设置 waiting_human
4. Ticker 检测到 waiting_human → 跳过调度
5. 前端轮询检测到 waiting_human + checkpoint → 渲染 CheckpointPanel
6. 用户 approve/reject
7. 后端自动推进状态 → working/done
8. Ticker 下次 tick 继续调度
```

### 4.7 前端 CheckpointPanel 组件

文件已存在：`CheckpointPanel.tsx`（350 行），未被引用。**扩展不重写**，对接 v2.8 新 API。

在 TaskModal 中当 `status=waiting_human` 时自动显示 CheckpointPanel：
- **验证面板**：自动核验结果 ✅/❌ + 人工核验步骤 + 预览链接 + 双按钮
- **决策面板**：三列方案卡片 + 利弊 + 推荐 + 御批备注 + 确认
- **执行面板**：步骤列表（可打勾）+ 命令行高亮 + 进度条 + 验证确认

---

## 五、Artifact 成果物面板（M3）

### 5.1 后端

扩展现有 `outputs` 表：

```sql
ALTER TABLE outputs ADD COLUMN file_name TEXT;
ALTER TABLE outputs ADD COLUMN file_size INTEGER;
ALTER TABLE outputs ADD COLUMN file_path TEXT;       -- NAS/本地路径
ALTER TABLE outputs ADD COLUMN mime_type TEXT;
```

API：
```
GET  /api/projects/{pid}/tasks/{tid}/outputs                   — 列出成果物
GET  /api/projects/{pid}/tasks/{tid}/outputs/{oid}/download    — 下载文件
```

### 5.2 前端 ArtifactPanel 组件

文件已存在：`ArtifactPanel.tsx`（185 行），未被引用。**扩展不重写**。

- **文件类型图标**：📄文档 / 💻代码 / 📊数据 / ⚙️配置 / 📁其他
- **卡片布局**：文件名 + 类型标签 + 大小 + 时间 + 下载按钮
- **下载**：直接下载

---

## 六、影响范围

### 后端（8 文件）

| 文件 | 改动 | 阶段 |
|------|------|------|
| `db.py` | CHECK 约束加 3 状态 + archived 字段 + checkpoints 表 | v2.8 |
| `models.py` | Task 加 archived/archived_at | v2.8 |
| `operations.py` | 归档方法 + 状态转换 + Checkpoint CRUD | v2.8+M3 |
| `queries.py` | 聚合规则更新 | v2.8 |
| `blackboard_routes.py` | 归档 API + title 自动生成 + 新状态 | v2.8 |
| `ticker.py` | 调度规则 + 聚合更新 | v2.8 |
| **新增** `checkpoint_routes.py` | Checkpoint CRUD API | M3 |
| `main.py` | 注册 checkpoint router | M3 |

### 前端（7 文件）

| 文件 | 改动 | 阶段 |
|------|------|------|
| `EdictBoard.tsx` | 两行布局 + 项目下拉 + 卡片按钮 + 新状态 | v2.8 |
| `TaskModal.tsx` | 新状态转换按钮 | v2.8 |
| `App.tsx` | 移除 header 项目 select | v2.8 |
| `store.ts` | 全项目聚合 + 归档 + 新状态 | v2.8 |
| `api.ts` | 新 API | v2.8+M3 |
| `CheckpointPanel.tsx` | 扩展对接新 API | M3 |
| `ArtifactPanel.tsx` | 扩展对接新 API | M3 |

---

## 七、实施计划

### Phase 1：v2.8 后端状态增强
1. `db.py` — schema migration + CHECK + MANUAL_STATUSES
2. `models.py` — archived/archived_at
3. `operations.py` — 归档方法 + 新状态转换
4. `queries.py` — 聚合规则
5. `blackboard_routes.py` — 归档 API + title 自动生成
6. `ticker.py` — 调度规则
7. 测试验证

### Phase 2：v2.8 前端改造（可与 Phase 3 并行）
1. `store.ts` — 全项目聚合 + 归档
2. `EdictBoard.tsx` — 两行布局 + 项目下拉 + 卡片按钮
3. `App.tsx` — 移除 header select
4. `TaskModal.tsx` — 新状态按钮
5. 前端构建验证

### Phase 3：M3 Checkpoint 后端（可与 Phase 2 并行）
1. checkpoints 表 + CRUD
2. checkpoint_routes.py（approve/reject 推进表写入注释）
3. Agent 触发流程
4. outputs 表扩展

### Phase 4：M3 前端（依赖 Phase 2 + 3）
1. CheckpointPanel.tsx 对接 API
2. ArtifactPanel.tsx 对接 API
3. TaskModal 集成
4. E2E 测试

### Phase 5：集成 + 部署
1. 全量测试
2. 前端构建
3. 部署上线

---

## 八、评审记录

| # | 时间 | 内容 |
|---|------|------|
| Mail #303 | 2026-05-18 22:45 | 庞统发设计文档给司马懿 |
| Mail #304 | 2026-05-18 22:48 | 司马懿评审：BUG-29（escalated 字段冲突）+ BUG-30（approve 推进）+ 5 OBS + 2 Q |
| Mail #304 | 2026-05-18 22:50 | 庞统回复：BUG-29 废弃布尔改 status、BUG-30 明确推进规则、采纳 OBS-30/32/33 |
| Mail #305 | 2026-05-18 22:51 | 司马懿最终结论：✅ 评审通过 |
