Files
sanguo_moziplus_v2/docs/design/architecture-v3.0.md
T
2026-06-04 22:04:00 +08:00

1989 lines
90 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Native DevOps Platform 架构设计 v3.0
**版本**: v3.0PRD 3.0 对齐版)
**基于**: PRD-v3.0 + architecture-v2.6 + v2.7~v3.0 增量设计 + 实际源码回溯
**作者**: 庞统(副军师)
**日期**: 2026-05-28(最后更新 2026-06-04
**状态**: v3.0 正式版(T1 清理完成,T 阶段规划已补充)
---
## §1. 版本信息和变更历史
### 1.1 版本演进
| 版本 | 日期 | 变更内容 |
|------|------|---------|
| v2.0 | 2026-05-04 | 初始版本:SQLite 4表 + 状态机 + DAG 引擎 |
| v2.6 | 2026-05-15 | 架构重构:Shared Workspace(Blackboard) 取代 DAG 引擎 |
| v2.6.1 | 2026-05-15 | 司马懿评审 + Mail 退役 + 质量门控 + 决策记录 |
| v2.6.2 | 2026-05-15 | 三层执行模型 + 续杯机制 + Guardrail 体系 |
| v2.6.3 | 2026-05-15 | 事件驱动 + Inbox JSONL + 依赖驱动 |
| v2.6.4 | 2026-05-15 | 分级审查流水线 + 反驳权 + reviews 表 |
| v2.6.5 | 2026-05-15 | 模板组件库 + 四层上下文架构 (L0-L3) |
| v2.6.7 | 2026-05-15 | 经验沉淀闭环 |
| v2.7 | 2026-05-18 | Card 层回滚 → Task 自引用 SubTask 模型 |
| v2.8 | 2026-05-18 | 3 新状态 (paused/escalated/waiting_human) + 归档机制 |
| v2.7.2 | 2026-05-26 | 防重复调用 & 防无限续杯 + counter v2.1 |
| v3.0 | 2026-05-28 | **本版**PRD 3.0 对齐 + 源码回溯 + 完整现状记录 |
| v3.0.1 | 2026-05-28 | 补充6个讨论话题(§6.5/§10.4~10.6+ 新增§21 T阶段规划(T1~T6 |
| v3.0.2 | 2026-05-29 | §12.3 Mail API 防御 + Prompt 约束设计(纳入司马懿评审意见);§6.5 补充 spawn 改造方向 |
| v3.0.3 | 2026-05-30 | §6.3.1 Session Lock 实测结论 + L3a/L3b/L3c 有效性分析 + Bug 修复(outcome 白名单 + 详细日志) |
| v3.0.4 | 2026-06-04 | 新增 §22 Pipeline 强工作流设计(TODO+ §8.1 Router 标注 TODO |
### 1.2 v3.0 定位
本文档是基于 PRD-v3.0 和实际源码的回溯性架构文档。目的:
1. **以 PRD 3.0 为准绳**,记录系统的设计目标
2. **以代码实际状态为事实**,记录已实现和未实现的功能
3. **记录所有设计矛盾和差异**,作为后续迭代的输入
4. **不盲从旧设计(v2.6**,以 7 条分类原则确定每项功能的真实状态
### 1.3 7 条分类原则
| # | 情况 | 处理 | 标记 |
|---|------|------|------|
| 1 | PRD ✅ + 代码 ✅ + 设计 ✅ | 直进 v3.0 | ✅ **已实现** |
| 2 | PRD ✅ + 代码 ❌ + 设计 ❌ | v3.0 标"待实现" | ❌ **未实现** |
| 3 | 调研/专题 ✅ + PRD ✅ + 代码 ❌ | v3.0 标"待实现" | ❌ **未实现** |
| 4 | 调研 ✅ + PRD ❌ | 标记为 PRD 新增项 | 📋 **PRD 待升级** |
| 5 | 代码 ✅ + PRD ❌ + 设计 ❌ | 找来源 → 归入1~3 或标"幽灵实现" | 👻 **幽灵实现** |
| 6 | 设计文档间矛盾 | 以 PRD 为准 | 🔀 **矛盾** |
| 7 | 调研有但 PRD 不值得进 | 归档保留,不进 v3.0 | 📦 **归档** |
---
## §2. 架构总览
### 2.1 核心变革:从 DAG 状态机到 Shared Workspace
v2.0 的核心是 **DAG 引擎 + 状态机 + 邮件通信**,本质是给 AI 团队做 ERP。v2.6+ 变革为 **Shared Workspace (Blackboard) + Agent 自主决策 + Daemon 投递**
```
┌─────────────────────────────────────────────────────────────┐
│ 用户 / 触发器 │
│ (Web Dashboard / CLI / Agent 对话) │
└──────────────────────────┬──────────────────────────────────┘
│ HTTP API / Agent 对话
┌──────────────────────────▼──────────────────────────────────┐
│ FastAPI (端口 8083) │
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ blackboard │ │ mail_routes │ │ project_routes │ │
│ │ _routes.py │ │ (Mail Tab) │ │ (项目管理) │ │
│ └───────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ └────────────┬────┘ │ │
└───────────────────────┼─────────────────────────┼───────────┘
│ SQLite │ registry.db
┌───────────────────────▼─────────────────────────▼───────────┐
│ Shared Workspace (黑板) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ per-project blackboard.db (SQLite WAL) │ │
│ │ tasks / comments / outputs / decisions / observations │ │
│ │ events / reviews / task_attempts / checkpoints │ │
│ └────────────────────────────────────────────────────────┘ │
│ ┌──────────────┐ │
│ │ registry.db │ ← 多项目注册表 (ProjectRegistry) │ │
│ └──────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ Daemon tick (30s) + Inbox JSONL (1s)
┌──────────────────────────▼──────────────────────────────────┐
│ Daemon (管家) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Ticker │ │ Dispatcher │ │ Spawner │ │
│ │ 30s 主循环 │ │ 路由决策+执行│ │ 进程管理+监控 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────────┘ │
│ │ │ │ │
│ ┌──────▼───────┐ ┌──────▼───────┐ ┌──────▼───────────┐ │
│ │ Router │ │ Counter │ │ Guardrails │ │
│ │ 确定性路由 │ │ 并发控制 │ │ 安全红线引擎 │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Health │ │ Experience │ │ InboxWatcher │ │
│ │ 僵尸检测 │ │ 经验蒸馏 │ │ 秒级事件推送 │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Bootstrap │ │ SSE Broker │ │ ReviewPipeline │ │
│ │ 上下文构建 │ │ 实时推送 │ │ 产出验证流水线 │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ openclaw agent --agent <id> --session-id <uuid>
┌──────────────────────────▼──────────────────────────────────┐
│ Agent 层 (将军们) │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │庞统 │ │司马懿│ │姜维 │ │关羽 │ │张飞 │ │赵云 │ │
│ │策划 │ │质量 │ │平台 │ │风控 │ │编码 │ │数据 │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │
│ 每个 Agent: SOUL.md + IDENTITY.md + Skills + Workspace │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 核心原则 ✅
> **黑板是唯一真相源,所有 agent 读它、想、行动,写回结果。Daemon 是投递员,不是决策者。**
| # | 原则 | 实现状态 |
|---|------|---------|
| 1 | Agent 决策,Daemon 执行 | ✅ 已实现 — Router 做确定性路由,模糊场景 delegate 庞统 |
| 2 | 产出在黑板,不在邮件 | ✅ 已实现 — outputs 表 + content_path 模式 |
| 3 | Daemon 不阻塞 Agent | ✅ 已实现 — async spawn + counter 并发控制 |
| 4 | Session 用完即清 | ⚠️ 部分实现 — spawn 隔离 session ✅,jsonl 存档和清理代码存在但未完全集成 |
| 5 | 双入口,对等地位 | ⚠️ 部分实现 — API ✅,Dashboard 前端存在但 AI Native 化未完成 |
### 2.3 v2.0 vs v3.0 对比
| 维度 | v1.0 (v2.0 原型) | v3.0 现状 |
|------|-----------------|----------|
| 编排核心 | DAG 引擎 + 状态机 | Blackboard (Shared Workspace) |
| 决策者 | Daemon (状态机驱动) | Agent (确定性路由 + delegate 庞统) |
| Daemon 角色 | 调度器 | 投递员 + 路由 + 监控 |
| Agent 通信 | Sanguo Mail (异步邮件) | 黑板 Comment + Mail Tab (兼容保留) |
| 信息位置 | 分散 | 集中 (per-project SQLite) |
| 状态机 | 8 个状态 | 11 个状态 (v2.8) |
| 上下文 | 全量注入 | L0-L3 四层分层 |
---
## §3. 核心原则(对齐 PRD 四条信念)
### 3.1 B1: AI 帮人想清楚要什么 ⚠️
| 方面 | PRD 目标 | 实际状态 |
|------|---------|---------|
| 苏格拉底式对话 | 需求探索的核心入口 | ✅ 已有 skill — `requirement-clarification`(加权模糊度评分 + 节奏守卫 + 停止守卫) |
| 多轮需求澄清 | 庞统通过对话帮用户梳理需求 | ✅ 已有 skill — `requirements-analysis`(需求规格化 + 假设标注 + 交付物定义) |
| 需求探索自动触发 | PRD Phase 1 自动启动 | ❌ 未实现 — Skill 存在但无 Daemon 自动触发机制 |
**现状**: Skill 层面完备(`requirement-clarification` + `requirements-analysis` 覆盖需求澄清全流程),但编排层面缺少自动触发。当前依赖 Agent 手动加载 Skill 或用户显式触发。
**差距**: 需要一个"需求探索"入口,当用户提一个模糊方向时,自动触发苏格拉底式对话。可在庞统主 session 通过 Skill 匹配实现,或在 Dashboard 新建任务时自动引导。
### 3.2 B2: 编排层是 AI 指挥官 ✅
| 方面 | PRD 目标 | 实际状态 |
|------|---------|---------|
| AI 驱动决策 | 庞统全程指挥 | ✅ 已实现 — Router 模糊场景 delegate 庞统 (v3.0) |
| 确定性兜底 | 底层执行保障 | ✅ 已实现 — Ticker 30s 循环 + 状态机 |
| 动态规划 | 计划可演进 | ⚠️ 基础机制存在(任务创建/状态流转),但无活的计划调整 |
### 3.3 B3: Agent 共享意识 ✅
| 方面 | PRD 目标 | 实际状态 |
|------|---------|---------|
| 共享状态空间 | Daemon HTTP API | ✅ 已实现 — FastAPI 端点齐全 |
| 实时感知 | Agent 按需查询黑板 | ✅ 已实现 — API 契约完整 |
| 不传消息 | 黑板评论替代邮件 | ✅ 已实现 — comments 表 + @mention |
### 3.4 B4: 人退到系统边缘 ✅
| 方面 | PRD 目标 | 实际状态 |
|------|---------|---------|
| 安全红线拦截 | 危险操作强制人工确认 | ✅ 已实现 — GuardrailEngine 6 条红线 |
| 关键决策点介入 | escalated/waiting_human 状态 | ✅ 已实现 — v2.8 新增 3 个状态 |
| SSE 实时推送 | AI 主动汇报 | ✅ 已实现 — SSEBroker + 前端 EventSource |
---
## §4. 系统架构图
### 4.1 数据流
```
用户 (Web/对话)
├─ POST /api/projects/{pid}/tasks → 创建任务 → blackboard.db
├─ POST /api/mail → 发送邮件 → _mail/blackboard.db
├─ GET /api/projects/{pid}/tasks → 查看任务
Daemon Ticker (30s 循环)
├─ 扫描 active 项目
├─ 依赖推进 (blocked → pending)
├─ 超时检测 (claimed 5min → pending, working 30min → failed)
├─ 调度 pending 任务 → Router → Dispatcher → Spawner
├─ 调度 review 任务 → Router → 匹配审查者
├─ 僵尸检测 (HealthChecker)
├─ 父 Task 聚合刷新
└─ daemon_tick 事件写入
Spawner (进程管理)
├─ counter acquire (per session key)
├─ session state 检查 (防 webchat 冲突)
├─ spawn openclaw agent 进程
├─ _monitor_process (630s 超时监控)
│ ├─ A1~A12: 进程退出场景分类
│ └─ B1~B4: 进程不退出场景分类
├─ 续杯机制 (Gateway timeout → 复用 session)
└─ wrapped_on_complete → counter release
Agent 执行
├─ 读黑板 (GET /tasks, GET /tasks/{id}?expand=all)
├─ 认领任务 (POST /tasks/{id}/claim) — CAS 原子操作
├─ 写产出 (POST /tasks/{id}/outputs)
├─ 写评论 (POST /tasks/{id}/comments)
├─ 更新状态 (POST /tasks/{id}/status)
├─ 写观察 (POST /tasks/{id}/observations — 通过 comments)
└─ 写决策 (POST /tasks/{id}/decisions — 通过 comments)
```
### 4.2 并发控制流
```
Ticker._dispatch_pending()
├─ 确定性路径:
│ ├─ retry → 原执行者
│ ├─ next_capability → 能力匹配
│ ├─ 有 assignee → 直接分
│ └─ review 生命周期 → 能力匹配
└─ 模糊路径 → delegate 庞统
```
---
## §5. 数据模型
### 5.1 数据库架构 ✅
**per-project SQLite**:每个项目独立 `blackboard.db`,全局 `registry.db` 管理项目注册表。
#### 5.1.1 tasks 表 ✅
```sql
CREATE TABLE tasks (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
status TEXT NOT NULL DEFAULT 'pending',
CHECK (status IN ('pending','claimed','working','review','paused',
'escalated','waiting_human','done','failed',
'blocked','cancelled')),
assignee TEXT,
assigned_by TEXT,
depends_on TEXT, -- JSON array of task IDs
parent_task TEXT, -- 父任务 (Task 自引用)
priority INTEGER NOT NULL DEFAULT 5,
task_type TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
claimed_at TEXT,
started_at TEXT,
completed_at TEXT,
deadline TEXT,
retry_count INTEGER NOT NULL DEFAULT 0,
max_retries INTEGER NOT NULL DEFAULT 2,
must_haves TEXT, -- JSON
risk_level TEXT DEFAULT 'standard',
estimated_duration_minutes INTEGER,
escalated INTEGER DEFAULT 0,
current_agent TEXT, -- v2.6.1 路由扩展
previous_agent TEXT,
next_capability TEXT,
stage TEXT, -- v2.7 所属 Stage 标签
stages_json TEXT DEFAULT '[]', -- v2.7 动态 Stage 定义
archived INTEGER DEFAULT 0, -- v2.8 归档
archived_at TEXT
);
```
**实现状态**:
- ✅ 11 个状态完整实现 (db.py `VALID_STATUSES`)
-`VALID_TRANSITIONS` 完整状态机 (v3.1 扩展了 paused 的恢复)
-`stages_json` 字段 (v2.7 SubTask 模型)
-`archived` / `archived_at` (v2.8 归档)
-`resumed_from` 字段 (v3.1 暂停恢复,在 models.py 中)
- ⚠️ `escalated INTEGER` 保留但设计要求改用 `status == 'escalated'`(向后兼容)
#### 5.1.2 comments 表 ✅
```sql
CREATE TABLE comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id TEXT NOT NULL,
author TEXT NOT NULL,
comment_type TEXT NOT NULL DEFAULT 'general',
CHECK (comment_type IN ('general', 'handoff', 'observation', 'rebuttal',
'rebuttal_response', 'debate_argument', 'debate_rebuttal', 'debate_judgment')),
body TEXT NOT NULL,
mentions TEXT, -- JSON array
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
```
- ✅ 8 种 comment_type 全部实现
-@mention 支持 (JSON 数组)
#### 5.1.3 outputs 表 ✅
```sql
CREATE TABLE outputs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id TEXT NOT NULL,
agent TEXT NOT NULL,
output_type TEXT NOT NULL,
title TEXT NOT NULL,
content_path TEXT,
summary TEXT,
metadata TEXT, -- JSON
attempt_number INTEGER DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
-- v2.8 M3 扩展字段:
file_name TEXT,
file_size INTEGER,
file_path TEXT,
mime_type TEXT
);
```
- ✅ 核心字段全部实现
- ✅ content_path 模式 (文件路径引用)
- ✅ content 直传模式 (后端自动写文件)
- ✅ M3 扩展字段 (file_name/file_size/file_path/mime_type)
#### 5.1.4 其他表 ✅
| 表名 | 状态 | 说明 |
|------|------|------|
| decisions | ✅ | 决策记录 (decider + decision + rationale + alternatives) |
| observations | ✅ | 观察记录 (observer + severity + body + resolved_by) |
| events | ✅ | 事件日志 (task_id + agent + event_type + detail JSON) |
| agents | ✅ | Agent 注册表 (agent_id + role + current_status + capabilities) |
| task_attempts | ✅ | 任务尝试记录 (attempt_number + outcome + exit_code + metadata) |
| reviews | ✅ | 审查记录 (review_type + verdict + confidence + round) |
| experiences | ✅ | 经验记录 (category + summary + confidence + tags) |
| experience_tags | ✅ | 经验标签 |
| checkpoints | ✅ | Checkpoint (M3: type + payload + status) |
### 5.2 状态机 ✅
**v3.1 完整状态转换矩阵** (11 个状态):
```python
VALID_TRANSITIONS = {
"pending": {"claimed", "paused", "blocked", "cancelled"},
"claimed": {"working", "paused", "pending", "cancelled"},
"working": {"review", "done", "blocked", "failed", "paused",
"escalated", "waiting_human", "cancelled"},
"paused": {"working", "claimed", "review", "escalated",
"waiting_human", "cancelled"},
"review": {"done", "pending", "failed", "paused", "escalated",
"waiting_human", "cancelled"},
"blocked": {"pending", "escalated", "cancelled"},
"failed": {"pending", "escalated", "cancelled"},
"escalated": {"working", "pending", "paused", "cancelled"},
"waiting_human": {"working", "done", "paused", "cancelled"},
"done": {"cancelled"},
"cancelled": {"pending"},
}
```
**与 v2.8 设计的差异** 🔀:
| 状态 | v2.8 设计 | v3.1 代码 | 差异 |
|------|----------|----------|------|
| paused 恢复 | → working | → working/claimed/review/escalated/waiting_human | 代码更灵活:恢复到 `resumed_from` 记录的状态 |
| pending | → {claimed, cancelled} | → {claimed, paused, blocked, cancelled} | 代码多了 paused、blocked |
| done | → set() | → {cancelled} | 代码允许取消已完成任务 |
| cancelled | → set() | → {pending} | 代码允许重新启动已取消任务 |
**手动状态** (不参与聚合): `cancelled`, `paused`
**聚合优先级**: escalated > waiting_human > review > working/claimed > pending > failed > blocked
### 5.3 项目注册表 ✅
-`registry.db` (SQLite) 管理多项目元数据
-`ProjectRegistry` 类:CRUD + 自动发现 + YAML 迁移
- ✅ 虚拟项目:`_mail` (飞鸽传书)、`_general` (一般任务)
- ✅ 自动发现:扫描含 `blackboard.db` 的目录
-`discover_sanguo_projects()`:扫描 `sanguo_projects/` 下的正式项目
### 5.4 版本迁移 ✅
| 迁移 | 文件位置 | 说明 |
|------|---------|------|
| v2.6.1 | `db._migrate_v261()` | current_agent, previous_agent, next_capability 字段 |
| v2.7 | `db._migrate_v27()` | stages_json, stage 字段 |
| v2.8 | `db._migrate_v28()` | 3 新状态 CHECK 约束重建 + 归档字段 + checkpoints 表 + outputs M3 扩展 |
---
## §6. Daemon 设计
### 6.1 Ticker 主循环 ✅
**文件**: `src/daemon/ticker.py` (~960 行)
```
Ticker.tick()
├─ 遍历 active 项目 (registry.list_projects())
├─ _tick_project(project_id, project_info):
│ ├─ init_db (首次)
│ ├─ 依赖推进 (blocked → pending)
│ ├─ _check_timeouts()
│ │ ├─ claimed 超时 (5min) → pending / escalated
│ │ ├─ working 超时 (30min) → failed
│ │ └─ 进程存活性检查 (PID alive)
│ ├─ _dispatch_pending()
│ │ └─ Dispatcher.dispatch() → Router → Spawner
│ ├─ _dispatch_reviews()
│ ├─ 僵尸检测 (HealthChecker.check())
│ ├─ 经验蒸馏 (ExperienceDistiller)
│ ├─ 父 Task 聚合刷新
│ └─ daemon_tick 事件写入
├─ 虚拟项目 _general (如果存在)
└─ 虚拟项目 _mail (如果存在)
```
**配置**:
- `tick_interval`: 30s
- `claim_timeout_minutes`: 5.0
- `default_task_timeout_minutes`: 30.0
- `max_dispatch_per_tick`: 3
**实现状态**:
- ✅ 30s 主循环
- ✅ per-project 扫描
- ✅ 依赖推进
- ✅ 超时检测 (claimed + working)
- ✅ 调度 pending/review 任务
- ✅ 僵尸检测
- ✅ 经验蒸馏调用
- ✅ 父 Task 聚合
- ✅ InboxWatcher 集成
-`max_dispatch_per_tick` 限制已实现,广播认领已实现(ticker.py `_broadcast_claim()`
### 6.2 Dispatcher 调度器 ✅
**文件**: `src/daemon/dispatcher.py` (~618 行)
**职责**:
1. 从 Router 获取路由决策
2. 执行 spawn (通过 Spawner)
3. 安全红线检查 (调度前拦截)
4. 写路由审计日志 (routing_decisions)
**调度级别**:
| 级别 | 说明 |
|------|------|
| LOCAL | Daemon 本地执行 |
| FULL_AGENT | Full Agent spawn |
| ESCALATE | 升级庞统 |
| BLOCKED | 安全红线拦截 |
**实现状态**:
- ✅ Router/Dispatcher 分层
- ✅ Guardrail 安全红线前置检查
- ✅ 路由审计日志
- ✅ Mail 自动标 working (v2.7.1)
- ✅ 续杯 message 构建
### 6.3 Spawner 进程管理 ✅
**文件**: `src/daemon/spawner.py` (~1270 行)
**核心能力**:
-`spawn_full_agent()`: 异步 spawn,含 counter acquire/release
-`_monitor_process()`: 630s 超时监控
- ✅ 情况 A (进程退出) 12 个场景分类 (A0~A12)
- ✅ 情况 B (进程不退出) 4 个场景分类 (B1~B4)
- ✅ 续杯机制 (Gateway timeout → 复用 session_id)
- ✅ spawn 前 session state 检查 (防 webchat 冲突)
- ✅ Mail 专用 prompt 模板 (inform/request)
- ✅ Spawn prompt 模板 (含完整 API 操作指引)
- ✅ BootstrapBuilder 集成
**spawn_full_agent 生命周期** (v2.7.2):
```
1. 分配 session_id
2. session state 检查 (main session 时)
3. counter.can_acquire() 三层检查
4. counter.acquire() 占用
5. spawn 进程
6. wrapped_on_complete 闭包 → counter.release (try/finally 保证)
```
### 6.3.1 Session Lock 实测结论 (v3.0.3)
> 2026-05-30 基于实际 Gateway 日志 + daemon 日志的联合分析
#### 三层防线 (L3a/L3b/L3c)
spawn 前检查 main session 状态(`_check_session_state`),三层防线:
```python
# spawner.py spawn_full_agent() 内
if use_main_session:
session_state = self._check_session_state(agent_id)
# L3a: lock 文件检查(唯一有效防线)
if session_state.get("lock_pid_alive"):
raise AgentBusyError(...)
# L3b: sessions.json status 检查(实测无效)
if session_state.get("status") == "running":
raise AgentBusyError(...)
# L3c: compact 检查
if session_state.get("recent_compact"):
raise AgentBusyError(...)
```
#### 实测数据 (2026-05-30 双邮件测试)
| 时间 | 事件 | status | lock_pid | alive | 拦截者 |
|------|------|--------|----------|-------|--------|
| 00:25:35 | spawn simayi (测试1) | done | None | False | ✅ 通过 |
| 00:26:05 | ticker 重试 simayi (测试2) | **done** | **75279** | **True** | **L3a** |
| 00:26:05 | spawn pangtong (处理回复) | done | None | False | ✅ 通过 |
| 00:26:36 | ticker 再试 simayi | done | 75279 | True | L3a |
| 00:30:38 | ticker 尝试 pangtong | **failed** | **75279** | **True** | **L3a** |
| 00:31:09 | spawn pangtong (回复) | done | None | False | ✅ 通过 |
#### 关键发现
1. **`sessions.json``status` 全程未出现 `running`**
- Gateway 处理 Agent turn 时,`sessions.json` 的 status 在 daemon 30s 采样间隔内不会变为 `running`
- 唯一可靠信号是 lock 文件(L3a)
- L3b 的 `status == "running"` 检查在实际场景中**从未触发**
2. **L3alock check)是唯一有效防线**
- 所有拦截都是 `lock_pid_alive=True`L3a
- L3b 修复(`"processing"``"running"`)是正确的但实测无效
3. **Gateway 内部存在二次 lock 竞争**
- Gateway 处理 CLI turn 时(持有 session write lock 5+ 分钟),内部会产生另一个请求也想写同一 session
- 表现为 `SessionWriteLockTimeoutError: timeout 60000ms`
- 这是 Gateway 内部并发问题,daemon 无法解决
- 02 架构改造(统一 main session)是根本解法
4. **status 字段可能出现 `failed`**
- 00:30:38 检查 pangtong 时 `status=failed`(上一次 turn lock 超时后 Gateway 写入)
- L3b 不检查 `failed`,此时只有 L3a 在守
#### 已修复的 Bug
| Bug | 问题 | 修复 | 影响 |
|-----|------|------|------|
| L3b 枚举值 | `"processing"` 应为 `"running"` | ✅ 已修复 | L3b 形同虚设,现恢复理论作用 |
| outcome 白名单 | `process_crash`/`unknown_status` 不在 CHECK 约束中 | ✅ 已映射到 `crashed`/`agent_error` | daemon 崩溃根因 |
| 无详细日志 | session state 检查通过时不打日志 | ✅ 已加 INFO 日志 | 下次出问题可追溯 |
#### TOCTOU 竞态(已知限制)
L3a 检查和 CLI subprocess 获取 write lock 之间存在时间差:
1. daemon 检查 `lock_pid_alive=False` → 通过
2. spawn CLI subprocess
3. CLI 连接 Gateway 请求 session write lock
4. 此时用户通过 webchat 发消息 → Gateway 持有 lock
5. CLI 等 60s 超时 → `SessionWriteLockTimeoutError`
这不是 daemon 能解决的问题,需要 02 架构改造(不再用 CLI spawn,统一投递到 main session)。
### 6.4 关键差异: 设计 vs 实现
| 设计文档 | 实际代码 | 状态 |
|---------|---------|------|
| 广播认领 (v3.0-router-refactor) | ticker.py `_broadcast_claim()` 已完整实现 | ✅ |
| Session 存档清理 | spawner 有 `_sessions` 注册表但清理逻辑未完整集成 | ⚠️ |
| L2 Subagent spawn | `spawner.spawn_subagent()` 存在但标注 TODO: F17 | ⚠️ 骨架已有 |
| `_parse_stdout_json` P0 修复 | 代码已修正为 `data["response"]["meta"]` 路径 | ✅ 已修复 |
---
### 6.5 Daemon 退化 + Agent 进化方向 📋
> 来源:v2.8-direction-notes §一~§二,2026-05-27 讨论
**核心理念**:Daemon 从调度器退化成投递员,Agent 从被动执行者进化成自主决策者。
> **黑板是精髓,不是任何单个 Agent。** 所有 Agent 读黑板、想、行动、写回。Daemon 是投递员,不是决策者。
**当前 vs 未来**
| 维度 | 当前(v2.7 实现) | 未来(AI Native v3.0 |
|------|------------------|---------------------|
| Daemon 角色 | 调度器 + 路由器 + 决策者 | 投递员 + 看护人 |
| Agent 角色 | 被动执行者(固定步骤 prompt) | 自主决策者(读黑板→想→干→写回) |
| 谁决定执行路径 | Daemonif/else + YAML | Agent(根据黑板信息自主判断) |
| Agent 间通信 | 无(Daemon 中央调度) | 黑板 comment + observation + @mention |
| Session 管理 | `--session-id UUID` → 新 session → 爆炸 | main session + subagent delegation |
**业界印证**
| 系统 | 做法 | 关键点 |
|------|------|--------|
| Claude Code Agent Teams | Agent 自己 flock() claim 任务 | Agent 自己决定看什么、干什么 |
| Hermes Kanban | Agent 有 kanban_* 工具直接操作黑板 | 工具驱动,不是 prompt 指令驱动 |
| PRD v3.0 | "黑板是唯一真相源" | peer-to-peer 感知 |
**明确不做的事**
1. ❌ Pipeline 框架(PipelineRouter 等不需要,Agent 自己决定执行策略)
2. ❌ 黑板摘要注入(Agent 已有 API 能力,让 Agent 自己决定看什么更 AI Native
3. ❌ blackboard_* 工具封装(优先级低,当前 curl + API 方式可用)
4. ❌ Skill 集群模板(和 Agent 自主决策矛盾)
**Spawn 改造方向**(详见 `docs/design/02-main-session-delegation.md`):
现行 `openclaw agent --session-id UUID` 导致 session 爆炸(E2E 测试 6 Agent 产生 68 个 session)。改造为:
- 所有 spawn 统一走 `spawn_full_agent(use_main_session=True)`(复用 Mail 路径已验证的模式)
- Agent main session 收到任务后自主决定执行方式(直接做 / sessions_spawn subagent / @mention 协作)
- subagent 通过 `cleanup: "delete"` 用完即删,不堆积
- 三层幻觉门控:Daemon 确定性检查 → 文件存在性验证 → AI 验证
> ⚠️ **澄清**:§10.5 Handoff Schema 不是 Pipeline 框架。Handoff 是 Agent 间的结构化交接文档(上家写给下家),是信息传递,不是执行编排。Pipeline 框架指的是 PipelineRouter/SingleStepPipeline 等代码级执行模式抽象,已明确不做。
**涉及文件**: `src/daemon/ticker.py``src/daemon/dispatcher.py``src/daemon/spawner.py``src/daemon/router.py`
**状态**: ❌ 方向已定,代码未动
---
## §7. Agent 交互设计
### 7.1 Agent-Backend API 契约 ✅
**文件**: `src/api/blackboard_routes.py` (~478 行)
| API | 方法 | 状态 | 说明 |
|-----|------|------|------|
| `/api/projects/{pid}/tasks` | GET | ✅ | 任务列表,支持 status/assignee/parent_task 过滤 |
| `/api/projects/{pid}/tasks` | POST | ✅ | 创建任务,自动生成 ID 和 title |
| `/api/projects/{pid}/tasks/{tid}` | GET | ✅ | 任务详情,expand=all 含全部关联数据 |
| `/api/projects/{pid}/tasks/{tid}/claim` | POST | ✅ | 原子 CAS 认领 |
| `/api/projects/{pid}/tasks/{tid}/status` | POST | ✅ | 状态更新,含合法转换校验 + SSE 推送 |
| `/api/projects/{pid}/tasks/{tid}/outputs` | GET/POST | ✅ | 产出 CRUD |
| `/api/projects/{pid}/tasks/{tid}/comments` | GET/POST | ✅ | 评论 CRUD |
| `/api/projects/{pid}/tasks/{tid}/decisions` | GET/POST | ✅ | 决策记录 |
| `/api/projects/{pid}/tasks/{tid}/observations` | GET/POST | ✅ | 观察记录 |
| `/api/projects/{pid}/tasks/{tid}/reviews` | GET/POST | ✅ | 审查记录 |
| `/api/projects/{pid}/tasks/{tid}/experiences` | GET/POST | ✅ | 经验记录 |
| `/api/projects/{pid}/tasks/{tid}/progress` | GET | ✅ | Stage 进度 + 子 Task 统计 |
| `/api/projects/{pid}/tasks/{tid}/archive` | POST | ✅ | 归档/取消归档 |
| `/api/projects/{pid}/tasks/archive-done` | POST | ✅ | 一键归档 |
| `/api/projects/{pid}/tasks/{tid}/outputs/{oid}/download` | GET | ✅ | 产出物下载 |
**Agent 友好的错误响应** ✅:
```json
{
"error": "invalid_transition",
"detail": "Cannot transition from claimed to review",
"valid_transitions": {"claimed": ["working", "pending", "cancelled"]},
"hint": "From 'claimed', valid targets are: ['working', 'pending', 'cancelled']"
}
```
**Title 自动生成** ⚠️ TODO: `blackboard_routes._generate_title()` 直接用 OpenAI client 调 zhipu API 生成标题(不走 Gateway),绕过了 Gateway 统一路由 + 计费。保留此函数,待未来替换为本地 LLM 调用。当前前端已支持传 titleLLM 生成只是 fallback。
### 7.2 CLI 工具 ✅
**文件**: `src/cli/blackboard.py` (~330 行)
支持的命令:
- `read` — 读取任务
- `create` — 创建任务
- `claim` — 认领任务
- `output` — 写产出
- `comment` — 写评论
- `decide` — 记录决策
- `observe` — 写观察
- `review` — 写审查
### 7.3 Agent 被 Spawn 后的工作流 ✅
```
1. 收到 spawn message (含 API 指引)
2. 标记 working (POST /tasks/{id}/status)
3. 执行任务 (编码/审查/数据等)
4. 写产出 (POST /tasks/{id}/outputs)
5. 写评论 (POST /tasks/{id}/comments) — 含 Handoff
6. 标记 review/done/failed
7. 进程退出 → Daemon 清理
```
### 7.4 Handoff Comment ✅
- ✅ comment_type = "handoff" 支持
- ✅ Schema 校验设计(schemas/ 目录定义)但 CLI 未集成校验
---
## §8. 路由与调度
### 8.1 AgentRouter 确定性路由 ✅
> **⚠️ TODO: Pipeline 强工作流**:当前 Router 只支持确定性路由 + 广播两种模式。Pipeline 强工作流(按 task_type 路由 + 状态机约束 + 直接 assign)待实现。详见文档末尾 §22 "Pipeline 强工作流设计" 章节。
**文件**: `src/daemon/router.py` (~180 行)
**v3.0 核心变更**: 去掉独立 LLM (LLMDriver),模糊场景 delegate 庞统。
**路由模式**:
```
route(task_info, action_type):
├─ LOCAL_ACTIONS → daemon 本地执行
├─ retry → 原执行者
├─ next_capability → 能力匹配 (排除当前 Agent)
├─ 生命周期流转 (review → review capability)
├─ 有 assignee → 直接分
└─ 模糊场景 → delegate 庞统 (L3 spawn, 走 Gateway)
```
**Agent 能力画像** ✅:
| Agent | 能力 | can_review | is_fallback |
|-------|------|-----------|------------|
| zhangfei-dev | coding, implementation, scripting | false | false |
| simayi-challenger | review, quality_check, debate | true | false |
| guanyu-dev | risk, compliance, position_check | true | false |
| zhaoyun-data | data, acquisition, cleaning, verification | false | false |
| jiangwei-infra | deploy, infrastructure, docker, vnpy | false | false |
| pangtong-fujunshi | planning, coordination, escalation, strategy | true | **true** |
**RouteDecision** ✅:
- `mode`: "deterministic" | "agent_handoff" | "delegate" | "fallback"
- `confidence`: 0.0~1.0
- `latency_ms`: 路由耗时
### 8.2 并发控制 ✅
**文件**: `src/daemon/counter.py` (~170 行)
**v2.1: per (agent, session) 粒度,三层控制**:
| 层级 | 配置 | 默认值 | 作用 |
|------|------|--------|------|
| per session key | `max_per_session` | 1 | 同一 (agent, session) 不能并发 spawn |
| per agent | `max_concurrent_sessions` | 3 | 同一 agent 最多同时跑 N 个不同 session |
| global | `max_global_agents` | 5 | 全局总并发上限 |
**冷却机制** ✅:
- `set_cooldown(agent_id, seconds=120)`: API 429 后冷却
- `is_cooling_down(agent_id)`: 检查冷却状态
### 8.3 广播认领 ✅(已实现,司马评审确认)— 定义修正 2026-06-04
**定义**:一轮广播 = 所有 Agent 都收到了任务并给出了反馈(认领/NO_REPLY),才算一轮完成。
**机制**
- 每个 pending 广播任务,维护 `notified_agents` 追踪已通知和已反馈的 Agent
- 每次 tick:spawn 空闲且尚未被通知的 Agent
- Agent 返回(认领/NO_REPLY/observation)→ 记录为已反馈
- Agent 忙(counter 阻塞)→ 不算已通知,下次 tick 继续尝试
- 当所有 Agent 都已反馈且没人认领 → 一轮结束 → retry_count +1
- 有人认领 → 广播立即结束(不需要等其他 Agent 反馈)
- 连续 3 轮广播无人认领 → 升级庞统
**实际代码 (ticker.py L540 `_broadcast_claim()`)**:
- ✅ 完整实现,包含:全局并发检查(counter.is_near_limit)、空闲 Agent 列表(_get_idle_agents)、批量广播(攒一批任务一次广播)、spawn 广播、无人认领检测(retry_count >= 3 → escalated)、审计事件记录(events 表 broadcast_claim 类型)
- ✅ 确定性路径也完整(Router → Dispatcher → Spawner
**与旧实现的区别**
- 旧:每次 tick spawn 所有空闲 Agent = 一轮,Agent 忙就跳过,retry_count 不递增
- 新:追踪每个 Agent 的通知/反馈状态,全部反馈才算一轮,防止忙 Agent 被反复跳过导致无限循环
**注**: 庞统初版误判为"未实现",因检查 router.py/spawner.py 时未查 ticker.py。司马懿评审纠正。
---
## §9. 质量门控/审查体系
### 9.1 ReviewPipeline ✅
**文件**: `src/daemon/review.py` (~335 行)
**验证链**: 产出物存在性 → 格式合规 → 内容质量 → 评分
| 步骤 | 检查内容 | 状态 |
|------|---------|------|
| Step 1: 存在性 | 产出文件是否存在 | ✅ |
| Step 2: 格式合规 | markdown/JSON 格式检查 | ✅ |
| Step 3: 内容质量 | 自定义检查 + 文件大小检查 | ✅ |
| Step 4: Guardrail 门控 | 低/中/高风险分级 | ✅ |
**门控级别**:
| 风险等级 | 门控 | 说明 |
|---------|------|------|
| low | automatic | 自动检查通过即完成 |
| standard | mandatory | 需人工审查 |
| high | dual | 双重审查 (对抗辩论) |
| extreme | dual | 双重审查 + 强制审批 |
### 9.2 分级审查流水线 ⚠️
**设计 (v2.6.4)**:
- ✅ high/standard/low/research 四级
- ✅ 三阶段: 方案审查 → Guardrail 自动 → 产出审查
- ✅ 反驳权 (Rebuttal Phase)
**实现状态**:
- ✅ ReviewPipeline 验证链
- ✅ reviews 表 + verdict 字段 (approved/rejected/needs_revision)
- ⚠️ 方案审查 (plan_review) — reviews 表支持 plan_review 类型 (db.py REVIEW_TYPES),但 Daemon 流程未自动触发方案审查
- ✅ 反驳权 — RebuttalManager (review.py) + 8 种 comment_type 含 rebuttal/debate 系列 + 前端 UI 支持
- ❌ 审查协议注册表 (review_protocols/) 未实现 — bootstrap.py 有 `_load_review_protocols` 但 review_protocols/ 目录不存在
- ❌ 对抗辩论模式未实现 — 无自动 spawn 正反方辩论
### 9.3 Guardrail 安全红线 ✅
**文件**: `src/daemon/guardrails.py` (~140 行) + `config/guardrails.yaml`
**PRD §10.1 六条红线**:
| 红线 | ID | 配置 | 代码 | 说明 |
|------|-----|------|------|------|
| 实盘交易 | live_trading | ✅ | ✅ | pattern 匹配 + task_type |
| 数据删除 | data_deletion | ✅ | ✅ | pattern 匹配 |
| 配置变更 | config_change | ✅ | ✅ | pattern 匹配 |
| 大额 Token | high_token_usage | ✅ | ✅ | token_threshold 检查 |
| Agent 不受控 | agent_uncontrolled | ✅ | ⚠️ | 规则定义在,但 step 超限检查未集成 |
| 连续失败 | consecutive_failure | ✅ | ✅ | consecutive_failures 检查 |
**GuardrailEngine 能力**:
-`check_task()`: 任务调度前检查
-`check_token_usage()`: Token 消耗检查
-`check_consecutive_failure()`: 连续失败检查
- ✅ pattern 正则匹配 + task_type 匹配
- ✅ action 分级: block_and_notify / pause_and_notify / terminate_and_escalate
---
## §10. 上下文管理
### 10.1 BootstrapBuilder 四层上下文 ✅
**文件**: `src/daemon/bootstrap.py` (~216 行)
| 层 | 内容 | Token 估算 | 状态 |
|----|------|-----------|------|
| L0 铁律层 | Hook 注入,不占 bootstrap | ~500 | ❌ 未集成到 Daemon |
| L1 角色层 | SOUL.md / IDENTITY.md (Agent 自带) | ~2000 | ✅ Agent 自有 |
| L2 引擎注入 | 操作规范 + 任务上下文 + 前序信息 + Guardrail + 审查协议 | ~1500 | ✅ BootstrapBuilder |
| L3 被动参考 | Skill description | 按需 | ✅ SkillRegistry |
**L2 注入内容 (按 role)**:
| 角色 | 注入内容 |
|------|---------|
| executor | role_template + 项目背景 + 任务上下文 + 前序产出 + Guardrail + 审查协议 + 经验 |
| reviewer | role_template + 项目背景 + 任务上下文 + 审查协议 |
| planner | role_template + 项目背景 + 任务上下文 + 审查协议 |
| pangtong | role_template + 项目背景 + 任务上下文 + 审查协议 |
**Token 预算**:
- `max_tokens`: 4096 (默认)
- 超限时自动截断
### 10.2 上下文预算 ✅
| 组件 | 预算 | 实际 |
|------|------|------|
| System Prompt + SOUL.md | ~3000-5000 | Agent 自有 |
| L2 引擎注入 | ~1000-2000 | BootstrapBuilder |
| 工作空间 | ~30000-50000 | Agent 剩余 context |
| **总计** | **~35K-60K** | 远小于 128K,安全 |
### 10.3 prompt_templates 目录 ⚠️
**设计**: `prompt_templates/executor.md`, `reviewer.md`, `planner.md` 等角色模板
**实现**: BootstrapBuilder 支持 `_load_template()` 加载模板文件,但实际的 prompt template 文件未完整创建。
### 10.4 Prompt 进化(固定步骤 → 自主决策)📋
> 来源:v2.8-direction-notes §三(2)2026-05-27 讨论
**问题**:当前 spawner 的 spawn prompt 把 Agent 限制在固定步骤(标 working → 干活 → 写产出 → 标 review),不够 AI Native。
**设计方向**:从"固定步骤指令"变成"身份 + 目标 + 能做什么 + 约束 + 交接责任":
```markdown
# 你的身份
你是 {agent_name}{agent_role}。擅长 {agent_capabilities}。
# 你的任务
{task_title}: {task_description}
类型: {task_type} | 风险: {risk_level}
必要条件: {must_haves}
# 你能做什么
通过 API 操作黑板({api_base}:
- 读任何任务详情: GET /api/projects/{pid}/tasks/{id}?expand=all
- 读所有活跃任务: GET /api/projects/{pid}/tasks
- 写产出: POST /api/projects/{pid}/tasks/{id}/outputs
- 写评论: POST /api/projects/{pid}/tasks/{id}/comments
- 更新状态: POST /api/projects/{pid}/tasks/{id}/status
- 创建子任务: POST /api/projects/{pid}/tasks
# 约束
- 完成后必须写产出 + 标 review
- 安全红线: {guardrails_summary}
- 超时: {timeout} 分钟
```
**核心变化**
1. Agent 自己根据黑板信息决定执行策略,不按固定步骤走
2. 给 Agent 黑板 API 完整能力列表,让 Agent 自主选择
3. 对齐 v3.0 "Daemon 退化 + Agent 进化"方向
> ⚠️ **注意**:新 prompt 中"约束"部分必须保留安全红线摘要(当前 GuardrailEngine 6 条红线已注入 prompt)。「自主决策」不意味着省略红线,红线是底线。
**涉及文件**: `src/daemon/spawner.py`spawn prompt 构建)、`prompt_templates/executor.md`(新建)
**状态**: ❌ 方向已定,prompt 模板未重写
### 10.5 Handoff 上下文(Agent 间交接)📋
> 来源:v2.8-direction-notes §三(3)2026-05-27 讨论
**问题**:Agent 完成任务后没有结构化的交接文档,下一个 Agent 缺少上下文。当前 handoff comment_type 已支持(§7.4),但无 Schema 约束和自动注入。
**设计方向**
1. 新建 `schemas/handoff.schema.json` — 定义 handoff comment 的结构化格式
2. `bootstrap.py` 增强 — spawn 时读取上一个 Agent 的 handoff comment 注入 prompt
3. Review 流程增加 handoff 检查 — 无 handoff comment 则提醒
4. `GET /comments?comment_type=handoff` API 已实现(§7.4),无需改动
**灵感来源**: MattPocock HandoffAgent 主动写交接文档传递上下文)
**涉及文件**: `schemas/handoff.schema.json`(新建)、`src/daemon/bootstrap.py``src/daemon/review.py`
**状态**: ❌ Schema 未创建,bootstrap 未增强
> 💡 **设计原则**handoff.schema.json 不要过度设计。核心字段建议只留:what_was_done(做了什么)、key_decisions(关键决策)、next_steps(建议下一步)、risks(已知风险)。其他让 Agent 自由写,不强制 Schema。
### 10.6 知识注入(L3 Wiki 知识 → Agent Prompt)📋
> 来源:v2.8-direction-notes §三(4) + §六,2026-05-27 讨论
**问题**Agent prompt 缺少领域知识,决策质量依赖 prompt 中的硬编码信息。当前 L3 层(§10.1)设计为"项目知识",但注入机制未实现。
**设计方向**
1. `spawner.py` 新增 `_inject_wiki_knowledge()` — 含 rg 检索 + grep fallback
2. `bootstrap.py` 内部调用 wiki knowledge 层
3. LLM Wiki 三层架构直接复用,不另建
> **澄清**LLM Wiki 指的是 `sanguo_mozi` 技能包中的 wiki 技能体系(wiki-vault 三层:practices/observations/patterns),位于 `/Volumes/KnowledgeBase/wiki-vault/`。复用方式:spawner 在 spawn Agent 前通过 rg 检索相关知识文档,将匹配结果注入 prompt(不依赖 Agent 自己调用 wiki skill)。
4. 知识检索日志记录(什么知识被注入了,效果如何)
**调研结论**(来自 v2.8-direction-notes §六):
| 方案 | 评估 | 结论 |
|------|------|------|
| Ripgrep 直接检索 | ✅ 最简单有效 | 采纳,作为主方案 |
| CodeGraph AST 索引 | ❌ 对知识文档无用 | 不采纳 |
| Understand Anything | ⚠️ 适合人工探索 | 不用于运行时注入 |
| MattPocock Handoff | ✅ Agent 交接 | 已采纳为 §10.5 |
**前置条件**: NAS `/Volumes/KnowledgeBase` 挂载路径问题需先解决(当前 `/Volumes/KnowledgeBase-1`
**涉及文件**: `src/daemon/spawner.py``src/daemon/bootstrap.py`
**状态**: ❌ 未实施
---
## §11. 前端
### 11.1 现有前端 ✅
**目录**: `frontend/` (Vite + React + TypeScript)
| 组件 | 状态 | 说明 |
|------|------|------|
| EdictBoard.tsx | ✅ | 任务看板 (卡片布局) |
| TaskModal.tsx | ✅ | 任务详情弹窗 |
| MailTab.tsx | ✅ | 邮件 Tab |
| SSE 集成 | ✅ | EventSource 实时推送 |
| 通知中心 | ✅ | SSE 事件通知 |
| CheckpointPanel.tsx | ✅ | Checkpoint 交互面板,集成到 TaskModal (waiting_human 状态) |
| ArtifactPanel.tsx | ✅ | 成果物预览/下载面板,集成到 TaskModal outputs tab |
### 11.2 v2.8 设计 vs 实现 ⚠️
| 设计 (v2.8-state-enhancement) | 实际前端 | 状态 |
|------|---------|------|
| 两行筛选栏 | 项目下拉 + 状态/搜索筛选 | ✅ 已实现 |
| 卡片快捷按钮 (⏸▶🚫) | TaskActionButtons 组件 | ✅ 已实现(含 resumed_from 恢复逻辑) |
| 新状态颜色 | STATUS_STYLES 映射表 | ✅ 已实现(11 个状态各有颜色标签) |
| 归档筛选 | 活跃/归档/全部三档 | ✅ 已实现 |
| Checkpoint 面板 | CheckpointPanel 集成 | ✅ 已实现 |
| Artifact 成果物 | ArtifactPanel 集成 | ✅ 已实现 |
### 11.3 Dashboard AI Native 化 ❌
**PRD 目标**: AI Briefing + 智能摘要 + 上下文感知布局
**实际**: 前端是传统的 CRUD 看板,无 AI Native 特性。
---
## §12. Mail 系统
### 12.1 Mail Tab ✅
**文件**: `src/api/mail_routes.py` (~240 行)
**设计**: Mail 是特殊的 Project (`_mail`),每封 Mail 是一个 Task。
| API | 方法 | 状态 |
|-----|------|------|
| `/api/mail` | GET | ✅ | 邮件列表 (时间倒序) |
| `/api/mail` | POST | ✅ | 发送邮件 (创建 Task) |
| `/api/mail/{id}` | GET | ✅ | 邮件详情 (含 comments 线程) |
| `/api/mail/agents/list` | GET | ✅ | 参与过 Mail 的 Agent 列表 |
| `/api/mail/summary` | GET | ✅ | 未读数 + 总数 |
**特性**:
-`conversation_id` 自动管理 (回复继承)
-`in_reply_to` 关联
-`type` 自动处理 (回复默认 inform 防循环)
- ✅ Mail spawn 时系统自动标 working
- ✅ Mail 续杯专用 prompt (不含状态转换指令)
### 12.2 与 v2.6 设计的关系 ✅(已澄清)
**v2.6 原文**: "Mail 完全退役,黑板替代所有功能" — 这里的 Mail 指的是 **sanguo_mail**(旧邮件系统),已被 v2.0 黑板完全替代。
**当前 Mail Tab**: 是 moziplus v2 内置的飞鸽传书功能(`_mail` 虚拟项目),是全新的实现,与 sanguo_mail 无关。两者不是同一个系统。
### 12.3 Mail API 防御 + Prompt 约束 📋
> 来源:#02 Main Session + Delegation 设计过程中发现的 Mail 自环问题
> 司马懿评审:mail-1780058519676 回复(M1/M2/S1-S3/A9),已纳入
#### 问题
Agent 回复邮件时把 `to` 写成自己,导致自环(mail-1780056763652 事件)。根因:
1. **API 层无防御**`send_mail` 不校验 `to` 的合法性,不自动推断回复收件人
2. **Prompt 层无约束**:回复模板中 `to` 字段要求 Agent 手动填写,Agent 容易写错
#### 设计约束
1. **Mail 是 Agent 间 1 对 1 通信**`from``to` 都必须是有效 Agent`from="user"` 不允许(用户收不到邮件)
2. **严格 1 对 1**。禁止第三方插入会话。多 Agent 协作走 Task(广播/mention
3. **有效 Agent 列表**统一维护一份,API 校验和 Prompt 模板共用同一数据源
#### API 层防御(`mail_routes.py` `send_mail`
**校验执行顺序**(按此顺序逐条校验,任一失败立即返回 400):
| 顺序 | # | 场景 | 校验逻辑 | 错误处理 |
|------|---|------|---------|----------|
| 1 | A1 | `from` 缺失/为空 | 必填校验 | 400"`from` 必填" |
| 2 | A9 | `from` 不是有效 Agent | 从注册 Agent 列表校验 | 400"`from` 不是有效的 Agent" |
| 3 | A5 | `in_reply_to` 指向不存在的邮件 | 原邮件存在性校验 | 400:"回复的邮件不存在" |
| 4 | A6/A7 | `in_reply_to` 存在时自动纠正 `to` | 自动从原邮件取 `assigned_by`(原发件者)作为 `to` | 静默纠正,响应中加 `auto_corrected` 提示 |
| 5 | A2 | `to` 缺失/为空(非回复) | 必填校验 | 400:"`to` 必填" |
| 6 | A3 | `from == to`(自环) | 防自环 | 400:"不能给自己发邮件" |
| 7 | A4 | `to` 不是有效 Agent | 从注册 Agent 列表校验 | 400"`to` 不是有效的 Agent" |
| 8 | A8 | `in_reply_to` 存在,`from` 不是原邮件的 `assignee``assigned_by` | 严格 1 对 1:只有原邮件的双方能回复 | 400:"只有邮件的发送者或接收者可以回复" |
| 9 | A10 | `text``description` 都为空 | 正文非空校验 | 400:"邮件正文不能为空" |
**关键设计说明**
- **A6/A7 自动纠正**:有 `in_reply_to` 时,无论 Agent 传什么 `to`,都自动从原邮件取 `assigned_by`(黑板字段,即原发件者)作为回复的 `to`。回复方向固定为 reply → original sender,不支持自定义收件人
- **A8 严格 1 对 1**:只有原邮件的 `assigned_by`(发件者)和 `assignee`(收件者)可以回复。其他人想参与需开新邮件,不能用 `in_reply_to` 插入别人的对话
- **A9 `from` 校验**`from` 必须是有效 Agent。现有代码 `body.get("from", "user")` 的默认值 `"user"` 需移除,改为必填
- **A4/A9 有效 Agent 列表**:同一数据源(从 ticker `self.agents` 或配置读取)。Prompt 模板也用此列表的 `{valid_agents}` 变量替换
**A6 自动纠正响应格式**
```json
{
"ok": true,
"mail_id": "mail-xxx",
"auto_corrected": {"field": "to", "original": "simayi-challenger", "corrected": "pangtong-fujunshi"}
}
```
让调用者知道 `to` 被纠正了,Agent 下次可以避免同样的错误。
#### Prompt 层约束(`spawner.py` 模板)
**当前问题**
1. 回复模板中 curl 命令的 JSON 双花括号转义,Agent 容易写错
2. 没有告诉 Agent "to 会自动推断"Agent 手动填写容易出错
3. 没有给 Agent "发新邮件" 的模板,Agent 自己猜格式
4. Agent ID 列表硬编码在模板字符串里,加 Agent 要改代码
**改动**
```python
MAIL_REQUEST_TEMPLATE = """你收到一封飞鸽传书,需要你处理并回复。
发件者: {from_agent}
主题: {title}
内容: {text}
### 如何回复发件者
curl -s -X POST http://localhost:8083/api/mail \\
-H 'Content-Type: application/json' \\
-d '{{"from": "{agent_id}", "in_reply_to": "{task_id}", "title": "回复: {title}", "text": "你的回复内容"}}'
⚠️ 不需要填 "to",系统自动回复给发件者。
### 如何给其他人发新邮件
curl -s -X POST http://localhost:8083/api/mail \\
-H 'Content-Type: application/json' \\
-d '{{"from": "{agent_id}", "to": "对方agent-id", "title": "标题", "text": "正文", "type": "inform"}}'
⚠️ to 必须是有效的 agent id: {valid_agents}
⚠️ 纯通知用 type=inform,需要对方回复不填 type(默认 request
⚠️ 不能给自己发邮件
⚠️ 不要执行任何状态转换命令(标 working/done/review/failed 等),系统会自动处理。
"""
MAIL_INFORM_TEMPLATE = """你收到一封飞鸽传书(纯通知)。
发件者: {from_agent}
主题: {title}
内容: {text}
已阅即可。如需回复,用 in_reply_to 回复发件者(不需要填 to)。
⚠️ 不要执行任何状态转换命令。
"""
```
**关键改动**
1. 回复模板去掉 `to` 字段,告诉 Agent "系统自动回复给发件者"
2. 新增"给其他人发新邮件"模板
3. Agent ID 列表用 `{valid_agents}` 运行时替换(和 A4/A9 同一数据源),不硬编码
4. 三条 ⚠️ 覆盖三种错误场景(自环 / 幻觉 agent / 状态误操作)
5. inform 模板也加上回复指引
#### 涉及文件
| 文件 | 改动 |
|------|------|
| `src/api/mail_routes.py` | `send_mail` 加 A1-A10 校验 + 自动推断 + 有效 Agent 列表 |
| `src/daemon/spawner.py` | 模板更新 + `{valid_agents}` 运行时替换 |
#### 状态
📋 设计已纳入司马懿评审意见,待确认 → 实施 → 验收
---
## §13. 经验沉淀
### 13.1 ExperienceDistiller ✅
**文件**: `src/daemon/experience.py` (~290 行)
**经验分类**:
| 类别 | 关键词 |
|------|--------|
| pitfall | bug/error/fail/陷阱/踩坑 |
| best_practice | should/recommend/最佳实践 |
| environment | install/configure/环境 |
| pattern | 通用模式 |
| decision | 决策记录 |
**ExperienceStore** ✅:
- JSONL 持久化
- add/get/search/delete/list_all
**ExperienceDistiller** ✅:
- 从 review 结果提取 pitfall
- 从 task 产出提取 best_practice
- 模式关键词匹配
### 13.2 经验注入 ✅
**BootstrapBuilder** 支持 `experiences` 参数,在 L2 层注入最多 5 条相关经验。
### 13.3 经验闭环 ⚠️
**设计 (v2.6.7)**: DISCOVER → DISTILL → APPLY → IMPROVE 闭环
**实际**:
- ✅ DISTILL: ExperienceDistiller 自动蒸馏
- ✅ APPLY: BootstrapBuilder 注入经验
- ❌ IMPROVE: 经验使用后反馈/更新机制未实现
- ❌ 一级蒸馏 (实时) + 二级蒸馏 (周期) 未区分
### 13.4 experiences 表 ✅
```sql
CREATE TABLE experiences (
experience_id TEXT PRIMARY KEY,
source TEXT,
task_id TEXT,
summary TEXT,
category TEXT,
confidence REAL DEFAULT 0.8,
status TEXT DEFAULT 'active',
skill_id TEXT,
usage_count INTEGER DEFAULT 0,
last_used_at TEXT,
created_at TEXT,
created_by TEXT,
updated_at TEXT,
deprecated_reason TEXT
);
```
---
## §14. Guardrail 体系
### 14.1 GuardrailEngine ✅
详见 §9.3。补充架构层信息:
**Guardrail 检查位置**:
1. **Dispatcher.dispatch()** — 调度前检查 ✅
2. **ReviewPipeline** — 产出写入后检查 ✅
3. **Ticker._check_timeouts()** — 超时触发检查 ✅
**违反后的行为**:
| action | 行为 |
|--------|------|
| block_and_notify | 阻止调度 + 写黑板事件 |
| pause_and_notify | 暂停任务 + 通知 |
| terminate_and_escalate | 终止 Agent + 升级 |
| pause_and_escalate | 暂停 + 升级 |
### 14.2 verification_commands ❌
**设计 (v2.6.9 借鉴1)**: 任务 Plan 中声明验证命令 (pytest, flake8 等)Daemon Guardrail 自动执行。
**实际**: ❌ 未实现。tasks 表无 `verification_commands` 字段。
### 14.3 Runaway Guard ⚠️
**设计 (v2.6.9 借鉴3)**: 每个任务最大 tick 上限 (max_ticks=100),超限暂停 + 告警。
**实际**: ⚠️ 部分实现。Ticker 有 `max_ticks` 参数(当前用于测试,限制 Ticker 自身运行次数),但不是 per-task 的 Runaway Guard。tasks 表无 `tick_count` / `max_ticks` 字段。需要扩展为 per-task 粒度。
---
## §15. 事件驱动
### 15.1 InboxWatcher ✅
**文件**: `src/daemon/inbox.py` (~306 行)
- ✅ JSONL 文件监听 (1s 轮询)
- ✅ truncate 模式 (清空内容不删除文件)
- ✅ 原子追加写入 (OS 保证 append 原子性)
- ✅ 异步回调处理
- ✅ 支持的事件: agent_output / agent_claim / agent_status / agent_heartbeat
**与 Ticker 的关系**:
```
Ticker.start()
├─ InboxWatcher.start() → 1s 轮询 inbox/daemon.jsonl
└─ _loop() → 30s 全量 tick
InboxWatcher 发现事件 → process_callback → mini-tick?
实际: process_callback 由 Ticker 注入,触发针对性处理
```
### 15.2 SSE 实时推送 ✅
**文件**: `src/daemon/sse.py` (~313 行)
- ✅ SSEBroker: 发布/订阅模式
- ✅ SSEEvent: 结构化事件 (id + type + data + timestamp)
- ✅ 100 条事件历史缓存
- ✅ subscriber 队列 (maxsize=100)
**Hook 系统** ✅:
- HookType: webhook / script / callback
- HookManager: 注册/注销/触发
- 支持超时控制 (10s)
### 15.3 事件类型 ✅
```python
SSEEventType:
TASK_CREATED, TASK_UPDATED, TASK_COMPLETED, TASK_FAILED,
OBSERVATION_ADDED, AGENT_SPAWNED, AGENT_COMPLETED,
DAEMON_TICK, REVIEW_RESULT, HOOK_TRIGGERED
```
---
## §16. 多项目支持
### 16.1 架构 ✅
**设计 (v2.6.10 方案C)**: 单 Daemon + 多数据库 + per-project 并发
**实际实现**:
| 组件 | 状态 | 说明 |
|------|------|------|
| per-project blackboard.db | ✅ | 每个项目独立 SQLite |
| registry.db | ✅ | 全局项目注册表 |
| ProjectRegistry | ✅ | CRUD + 自动发现 + YAML 迁移 |
| 虚拟项目 | ✅ | `_mail`, `_general` |
| 任务跨项目移动 | ✅ | `POST /api/projects/{pid}/tasks/{tid}/move` |
| per-project 并发线程 | ❌ | 当前是 asyncio 单线程顺序处理 |
### 16.2 项目管理 API ✅
| API | 方法 | 状态 |
|-----|------|------|
| `/api/projects` | GET | ✅ | 项目列表 (含实时任务统计) |
| `/api/projects` | POST | ✅ | 创建项目 |
| `/api/projects/{pid}` | GET | ✅ | 项目详情 |
| `/api/projects/{pid}` | PATCH | ✅ | 更新项目 |
| `/api/projects/{pid}/archive` | POST | ✅ | 归档项目 |
| `/api/projects/{pid}` | DELETE | ✅ | 逻辑删除 |
| `/api/projects/{pid}/tasks/{tid}/move` | POST | ✅ | 跨项目移动任务 |
---
## §17. 待实现项汇总(原则 2/3)
> ⚠️ 以下为庞统初判 + 用户复查 + 司马懿评审后的修正版本(v3)。
>
> **已清理的问题**(不在此列表中):
> - ~~P3 遗留 (404/4xx 响应码)~~: 已修复
> - ~~续杯设计矛盾~~: 已验证代码与设计一致
> - ~~广播认领矛盾~~: 已验证完整实现
> - ~~BUG-22 (list_mail from 内存过滤)~~: T1 修复,改为 SQL WHERE (assigned_by 参数)
> - ~~OBS-25 (send_mail from 冗余存储)~~: T1 修复,from 统一用 assigned_bymust_haves 不再存 from
> - ~~OBS-26 (polling 不刷新 Mail)~~: T1 修复,loadAll 在 mail tab 时调 loadMails()
### 17.1 PRD 明确要求但未实现
| # | 功能 | PRD 来源 | 当前状态 | 优先级 |
|---|------|---------|---------|--------|
| 1 | **需求探索自动触发** | PRD B1/C1 | ⚠️ Skill 已有(requirement-clarification + requirements-analysis),但缺少 Daemon 自动触发机制 | P2 |
| 2 | **动态规划** (活计划, 全程可调) | PRD B2/C2 | ❌ 基础机制存在(任务创建/状态流转),但无活的计划调整 | P1 |
| 3 | **持续指挥** (庞统全程在线) | PRD B2/C3 | ❌ 庞统只在 delegate 时被 spawn,无持续指挥 session | P1 |
| 4 | **主动汇报** (AI 推送自然语言摘要) | PRD B4/C7 | ⚠️ SSE 推送已有,但推送的是原始事件,不是 AI 生成的自然语言摘要 | P2 |
| 5 | **工具链集成** (lint/test/build) | PRD C10 | ❌ 未实现,toolchain-proposal.md 处于信息收集阶段 | P3 |
| 6 | **经验闭环 IMPROVE** | PRD C8 | ⚠️ DISTILL + APPLY 已实现,IMPROVE(使用后反馈/更新)未实现 | P3 |
### 17.2 设计文档有详细方案但未实现(经复查)
| # | 功能 | 设计文档 | 复查结果 | 优先级 |
|---|------|---------|---------|--------|
| 7 | ~~**广播认领** (自主 claim 调度)~~ | v3.0-router-refactor §3.3 | ✅ 已完整实现(ticker.py `_broadcast_claim()`),司马评审确认。移至 §17.3 | ~~P2~~ |
| 8 | **方案审查自动流程** | v2.6.4 §9.3 | ⚠️ reviews 表支持 plan_review 类型,但 Daemon 不会自动触发方案审查流程 | P2 |
| 9 | **审查协议注册表** (review_protocols/) | v2.6.4 §9.4 | ❌ bootstrap.py 有 `_load_review_protocols` 但 review_protocols/ 目录不存在 | P2 |
| 10 | **对抗辩论模式** (high 风险任务) | v2.6.4 §9.10 | ❌ 无自动 spawn 正反方辩论。comment_type 支持 debate 系列但无自动编排 | P3 |
| 11 | **verification_commands** (验证脚本层) | v2.6.9 借鉴1 | ❌ tasks 表无 verification_commands 字段,Guardrail 无脚本执行 | P2 |
| 12 | **Shadow Checkpoint** (git 自动 commit) | v2.6.9 借鉴5 | ❌ 无 git 集成 | P3 |
| 13 | **Skill 生命周期** (draft→active→deprecated) | v2.6.7 | ❌ SkillRegistry 只有注册/匹配,无生命周期管理 | P3 |
| 14 | **prompt_templates 角色模板** (完整文件) | v2.6.5 | ⚠️ BootstrapBuilder 支持 `_load_template()` 加载模板文件,但 prompt_templates/ 目录不存在 | P2 |
| 15 | **CLI Schema 校验** (schemas/ 目录) | v2.6.3 §3.7 | ❌ schemas/ 目录不存在 | P2 |
| 16 | **per-provider 冷却** | v2.7.2 §5 | ❌ Counter 只有 per-agent 冷却,无 per-provider 粒度 | P4 |
### 17.3 已确认实现(从待实现列表移除)
| # | 功能 | 证据 | 移除原因 |
|---|------|------|---------|
| — | **反驳权 (Rebuttal)** | ✅ RebuttalManager (review.py:273) + comment_type 含 rebuttal/debate_* + 前端 UI | 用户复查确认 |
| — | **Checkpoint 机制** | ✅ checkpoint_routes.py (6 端点) + CheckpointPanel.tsx + db.py checkpoints 表 | 用户复查确认 |
| — | **Artifact 成果物面板** | ✅ ArtifactPanel.tsx + ArtifactList.tsx + API 预览/下载端点 | 用户复查确认 |
| — | **广播认领** | ✅ ticker.py `_broadcast_claim()` 完整实现(全局并发检查 + 批量广播 + retry 3 次 + 庞统兜底) | **司马懿评审纠正** |
| — | **L2 Subagent spawn** | ⚠️ 骨架已有:spawner.spawn_subagent() 存在但标注 TODO: F17 | 部分实现 |
| — | **假死复活术** | ⚠️ health.py zombie 检测 + spawner._revive_session() | 部分实现 |
| — | **Runaway Guard** | ⚠️ Ticker 有 max_ticks(测试用),但不是 per-task 粒度 | 部分实现 |
---
## §18. PRD 新增建议(原则 4/5
### 18.1 调研有但 PRD 未涵盖(原则 4)
| # | 内容 | 来源 | 建议 |
|---|------|------|------|
| 1 | Skill System (三层自由度: 原则/模板/脚本) | SkillRegistry 代码 | PRD 应补充 C11: 可插拔技能体系 |
| 2 | Hook 系统 (webhook/script/callback) | SSEBroker + HookManager | PRD 应补充事件扩展机制 |
| 3 | per-project 并发隔离 | v2.6.10 方案C | PRD 应明确多项目并发模型 |
| 4 | Mail 保留 (与 PRD "Mail 退役"矛盾) | 实际代码 | PRD 应更新: Mail 作为辅助通道保留 |
### 18.2 幽灵实现(原则 5: 代码有但设计没提)
| # | 内容 | 代码位置 | 分析 |
|---|------|---------|------|
| 1 | **Title LLM 自动生成** | blackboard_routes._generate_title() | 代码直接调 zhipu API 生成标题,不走 Gateway。类似 v3.0 删除的 LLMDriver 问题(不走 Gateway,需单独维护凭据) |
| 2 | **任务跨项目移动** | project_routes.move_task() | 完整实现含子任务一起移动,但无对应设计文档 |
| 3 | **Mail conversation_id 自动管理** | mail_routes.send_mail() | 自动继承回复的 conversation_id,无设计文档记录 |
| 4 | **routing_decisions 审计日志** | dispatcher._record_routing() | 路由审计写入 routing_decisions 表,但 db.py 中该表定义在 schema 但未在模型中暴露 |
---
## §19. 设计矛盾记录(原则 6)
> ⚠️ 以下为庞统初判 + 用户复查后的修正版本。司马懿需重点验证:这些矛盾是否真实存在?是否是我们漏看了某个最新的设计专项?
### 19.1 状态机:v2.8 设计 vs v3.1 代码 ✅(已解决,以代码为准)
**决策**: 以代码实际实现为准,v2.8 设计文档已归档至 `archive-2.0/v2.8-state-enhancement.md`
**代码实际状态机**(§5.2 已完整记录):
- 11 个状态,VALID_TRANSITIONS 完整定义
- `TERMINAL_STATUSES = frozenset()` — 无终态,全靠转换矩阵校验
- `MANUAL_STATUSES = {cancelled, paused}` — 不参与聚合推导
- paused 恢复通过 `resumed_from` 字段记录暂停前状态
- done → cancelled、cancelled → pending 支持"反悔"操作
**与 v2.8 设计的关键差异**(已归档,不再维护):
- v2.8 定义了终态(done/cancelled),代码取消终态概念
- v2.8 paused 只能恢复到 working,代码支持恢复到任意 paused 前状态
- v2.8 pending 只能到 claimed/cancelled,代码多了 paused/blocked
这些差异都是工程实践中的合理扩展,代码更灵活实用。
### 19.2 广播认领 vs Delegate 庞统 ✅(已解决,非矛盾)
**v3.0-router-refactor 设计**: 双路径调度
- 确定性路径:已知下一步谁做 → 直接 spawn
- 广播认领路径:不确定 → spawn 所有空闲 Agent → 自主 claim
- 无人认领 → retry 3 次 → 庞统兜底
**实际代码 (已确认实现)**:
- ✅ 确定性路径:Router → Dispatcher → Spawner
- ✅ 广播认领路径:ticker.py `_broadcast_claim()` 完整实现
- ✅ 庞统兜底:retry_count >= 3 → escalated → delegate
**结论**: 设计和代码一致,双路径都完整实现。从矛盾列表移除。
**纠正记录**: 庞统初版只检查了 router.py/spawner.py,遗漏了 ticker.py L540。司马懿评审纠正。
**⚠️ 已知问题(2026-06-04 发现)**
- 广播计数器不递增:`_broadcast_claim` 中只检查 `retry_count >= 3` 但不递增 retry_count
- retry_count 只在 `_check_timeouts` 的 claimed 超时路径递增
- 导致广播任务无限循环:每 tick 广播一次,没人认领也不计数
- **修复方案**:见 `docs/design/12-pipeline-design.md` §5 广播定义修正
### 19.3 `_generate_title()` 绕过 Gateway ⚠️ TODO(保留,待替换本地 LLM)
**现状**: `blackboard_routes._generate_title()`line 138-175)直接用 OpenAI client 调 zhipu API,不走 Gateway。
**决策**: 保留此函数,不删除。未来替换为本地 LLM 调用。
**替换方向**: 本地 LLM(如 Ollama)或走 Gateway API。当前前端已支持传 titleLLM 只是 fallback,不影响正常使用。
### 19.4 续杯设计 ✅(已验证一致)
**spawner-monitor-design v2.0**: 续杯只有 A2/A3Gateway timeout)触发。
**实际 spawner 代码**: `_handle_exit``cls["should_retry"]` 为 True 时才走 `_do_retry`,注释明确 "只有 A2/A3gateway_timeout)触发续杯,其他都不 retry"。
**结论**: 代码和设计一致,不存在矛盾。删除此矛盾项。
---
### 19.5 Mail 模块硬编码问题 ⚠️ TODO(最后做 — 等其他专题稳定后再统一解决)
**现状**: `_mail` 作为虚拟 Project ID,在 dispatcher、spawner、blackboard_routes 中大量硬编码:
| 文件 | 硬编码位置 | 用途 |
|------|-----------|------|
| dispatcher.py L127,186 | `project_id == "_mail"` | 跳过 guardrail、标 working、on_complete |
| spawner.py L242,251,256 | `project_id == "_mail"` | 精简 prompt、直接 done 不走 review |
| blackboard_routes.py | `project_id == "_mail"` | 邮件 API 路由 |
**问题**:
1. 新增 Task 类型时需要到处加 `if project_id == "_xxx"` 分支
2. Mail 的特殊行为(精简 prompt、不走 review、auto-working)分散在多个文件
3. 没有统一的 Task 类型配置表
**设计方向**v2.8 TaskType Pipeline:
- 每个 Project 有 `task_type` 配置(mail/general/custom
- 行为差异通过策略模式解决:`TaskPipeline.execute(route → pre_spawn → spawn → post_complete → verify)`
- Mail 特殊逻辑收敛到 `MailPipeline`
**参考**: `docs/design/archive-2.0/v2.8-task-type-pipeline.md`(已设计未实施)
**当前 on_checks_passed 方案**v2.7.3 临时修复):
- spawner 新增 `on_checks_passed` 参数,check 通过后、subprocess 前回调
- dispatcher 传入 `_mail_auto_working` 作为回调
- subprocess 失败时通过 `_mail_marked_working` flag 决定是否 revert
- VALID_TRANSITIONS[working] 已加入 pending(正式合法化)
---
## §20. 技术选型
### 20.1 核心技术栈 ✅
| 需求 | 选型 | 理由 |
|------|------|------|
| Web 框架 | FastAPI (Python) | 异步 + 自动文档 + 类型安全 |
| 数据库 | SQLite (per-project) | 原子性 + WAL + 零外部依赖 |
| 前端 | React + Vite + TypeScript | SPA + 快速构建 |
| 进程管理 | asyncio.create_subprocess_exec | 异步非阻塞 spawn |
| 实时推送 | SSE (Server-Sent Events) | 单向推送,比 WebSocket 简单 |
| 事件加速 | Inbox JSONL | agent-chorus 模式,跨进程通信 |
| 配置 | YAML (default.yaml + guardrails.yaml) | 人可读 + 可版本化 |
| 进程守护 | PM2 (Node.js) | 自动重启 + 日志管理 |
| Agent CLI | openclaw agent | OpenClaw 原生能力 |
| LLM 路由 | OpenClaw Gateway | 统一模型路由 + fallback + 计费 |
### 20.2 关键配置参数
```yaml
daemon:
tick_interval: 30
max_global_agents: 5
max_per_session: 1
max_concurrent_sessions: 3
max_dispatch_per_tick: 3
claim_timeout_minutes: 5.0
default_task_timeout_minutes: 30.0
agent_timeout: 630
gateway_timeout: 600
max_retries: 3
max_monitor_timeouts: 3
api_host: "127.0.0.1"
api_port: 8083
zombie_threshold: 20
```
### 20.3 数据库连接配置 ✅
```python
PRAGMA journal_mode=WAL # 并发读写
PRAGMA foreign_keys=ON # 外键约束
PRAGMA busy_timeout=5000 # 写锁等待 5s
```
### 20.4 参考系统映射
| 参考系统 | 借鉴点 | 映射到 |
|---------|--------|--------|
| Hermes Kanban | SQLite + Dispatcher tick | 黑板 + Ticker 30s |
| agent-chorus | JSONL inbox 跨进程通信 | InboxWatcher |
| open-multi-agent | TaskQueue.complete() → unblockDependents | 依赖推进 |
| Claude Code | file reference 模式 | outputs.content_path |
| Opal-Bridge | Fidelity 三档 | L1/L2/L3 上下文分层 |
| GSD Wave Execution | 隔离 session + 新鲜 context | per-task session |
| TradingAgents | Bull vs Bear 对抗辩论 | 审查体系 (设计) |
| superpowers | 三种 reviewer 角色 | ReviewPipeline 分级 |
| Aider | lint→test→commit | verification_commands (设计) |
| claude-goal | Stop Hook + 完成审计 | Guardrail + Runaway Guard (设计) |
| Cline | Shadow Git Checkpoint | Shadow Checkpoint (设计) |
---
## 附录 A: 文件清单
### A.1 后端源码
| 文件 | 行数(约) | 职责 |
|------|---------|------|
| `src/main.py` | 300 | FastAPI 入口 + 组件初始化 + 生命周期 |
| `src/blackboard/db.py` | 450 | DB schema + 迁移 + 状态机常量 |
| `src/blackboard/models.py` | 200 | 数据类 (Task/Comment/Output/...) |
| `src/blackboard/operations.py` | 830 | 黑板 CRUD 操作 |
| `src/blackboard/queries.py` | 357 | 黑板只读查询 |
| `src/blackboard/registry.py` | 326 | 多项目注册表 |
| `src/daemon/ticker.py` | 960 | Ticker 主循环 |
| `src/daemon/dispatcher.py` | 618 | 调度器 (路由+spawn) |
| `src/daemon/spawner.py` | 1270 | 进程管理 + 监控 + 续杯 |
| `src/daemon/router.py` | 180 | 确定性路由决策 |
| `src/daemon/bootstrap.py` | 216 | 上下文构建 (L0-L3) |
| `src/daemon/counter.py` | 170 | 并发控制 + 冷却 |
| `src/daemon/guardrails.py` | 140 | 安全红线引擎 |
| `src/daemon/review.py` | 335 | 产出验证流水线 |
| `src/daemon/inbox.py` | 306 | Inbox JSONL 监听 |
| `src/daemon/experience.py` | 290 | 经验蒸馏 |
| `src/daemon/health.py` | 160 | 僵尸检测 |
| `src/daemon/sse.py` | 313 | SSE + Hook 系统 |
| `src/daemon/skill_system.py` | 248 | Skill 注册/匹配/执行 |
| `src/api/blackboard_routes.py` | 478 | 黑板 API 路由 |
| `src/api/mail_routes.py` | 240 | Mail API 路由 |
| `src/api/project_routes.py` | 190 | 项目管理 API |
| `src/cli/blackboard.py` | 330 | CLI 工具 |
### A.2 配置文件
| 文件 | 说明 |
|------|------|
| `config/default.yaml` | 全局配置 (daemon/agent_profiles/inbox/review/experience) |
| `config/guardrails.yaml` | 安全红线 6 条规则 |
### A.3 设计文档
| 文档 | 说明 |
|------|------|
| `docs/PRD-v3.0.md` | 产品需求文档 |
| `docs/design/architecture-v2.6.md` | v2.6 架构设计 (~2070 行) |
| `docs/design/v2.7-subtask-model.md` | SubTask 模型 (Task 自引用) |
| `docs/design/v2.8-state-enhancement.md` | 状态增强 + 归档 + Checkpoint |
| `docs/design/v2.7.2-counter-lifecycle-fix.md` | 防重复调用 & 防无限续杯 |
| `docs/design/v3.0-router-refactor.md` | 路由重构 (去 LLM, 广播认领) |
| `docs/design/spawner-monitor-design.md` | Spawner Monitor 设计 |
| `docs/design/agent-api-contract.md` | Agent API 契约 |
---
## 附录 B: 实现状态总览
| 模块 | 已实现 | 部分实现 | 未实现 |
|------|--------|---------|--------|
| **数据模型** | SQLite schema, 11 状态, Task 自引用, 归档, Checkpoint | — | — |
| **Daemon Ticker** | 30s 循环, 依赖推进, 超时, 僵尸检测, 广播认领 | — | — |
| **路由调度** | Router 确定性路由, delegate 庞统, 广播认领 | — | L2 Subagent |
| **Spawner** | 进程管理, 监控, 续杯, counter | Session 清理集成 | 假死复活术 |
| **质量门控** | ReviewPipeline, Guardrails 6 红线 | — | 方案审查, 反驳权, 对抗辩论 |
| **上下文** | BootstrapBuilder L0-L3 | prompt_templates 文件 | — |
| **前端** | 任务看板, Mail Tab, SSE | 新状态 UI | AI Native, Checkpoint/Artifact |
| **Mail** | 完整 Mail Tab + API | — | — |
| **经验沉淀** | Distiller, Store, 注入 | — | 闭环 IMPROVE, 一/二级蒸馏 |
| **事件驱动** | InboxWatcher, SSE Broker, Hook | — | — |
| **多项目** | Registry, per-project DB, 移动 | — | per-project 并发线程 |
| **安全** | Guardrails 6 线, Counter 并发 | — | verification_commands, Runaway Guard |
| **Skill** | SkillRegistry 三层自由度 | — | Skill 生命周期 |
| **需求探索** | — | — | 苏格拉底对话, 动态规划 |
| **主动汇报** | SSE 推送 | — | 自然语言摘要 |
**总计**: ✅ 已实现 25 项 | ⚠️ 部分实现 8 项 | ❌ 未实现 12 项
> 上述数据经 2026-05-28 用户复查 + 司马懿评审修正。广播认领从未实现移至已实现。
---
## §21. T 阶段规划(T1~T8
> 2026-05-28 新增,v3.0.1 更新。基于 architecture-v3.0 回溯 + v2.8-direction-notes 讨论话题 + §17/§19 待实现项 + 设计矛盾 + MEMORY/HEARTBEAT 遗留。
### 21.1 遗留问题完整清单(A/B/C/D 编号)
> 2026-05-28 08:44 规划,来源于 architecture-v3.0.md §17/§19 + HEARTBEAT.md + MEMORY.md 三路汇总。
| # | 来源 | 问题 | 类型 | 优先级 |
|---|------|------|------|--------|
| A1 | §17.1 #2 | **动态规划**(活计划,全程可调) | PRD 核心差距 | P1 |
| A2 | §17.1 #3 | **持续指挥**(庞统全程在线) | PRD 核心差距 | P1 |
| A3 | §19.1 | **状态机矛盾**(v2.8 设计 vs 代码,以代码为准更新文档) | 设计矛盾 | ~~P1~~ ✅ T1 已解决 |
| A4 | §19.3 | **`_generate_title()` 绕过 Gateway** | Bug | ~~P1~~ ✅ T1 已保留,待替换本地 LLM |
| B1 | §17.1 #1 | **需求探索自动触发**Skill 已有,缺 Daemon 触发机制) | PRD 差距 | P2 |
| B2 | §17.1 #4 | **主动汇报**(SSE 推原始事件,不是 AI 摘要) | PRD 差距 | P2 |
| B3 | §17.2 #8 | **方案审查自动流程**reviews 表有,Daemon 不触发) | 设计未落地 | P2 |
| B4 | §17.2 #9 | **审查协议注册表**review_protocols/ 不存在) | 设计未落地 | P2 |
| B5 | §17.2 #11 | **verification_commands**Guardrail 验证脚本层) | 设计未落地 | P2 |
| B6 | §17.2 #14 | **prompt_templates 角色模板**(目录不存在) | 设计未落地 | P2 |
| B7 | §17.2 #15 | **CLI Schema 校验**schemas/ 不存在) | 设计未落地 | P2 |
| B8 | MEMORY | **BUG-7** planning 暂停失败 | Bug | P2 |
| B9 | MEMORY | **BUG-8** cancel→resume 空图完成 | Bug | P2 |
| B10 | MEMORY | **P3 遗留** 404/4xx 响应码 | Bug | ~~P3~~ ✅ 已修复 |
| B11 | MEMORY | **v2.7 遗留** BUG-22/OBS-25/OBS-26 | P3 | ~~P3~~ ✅ T1 已修复 |
| C1 | §17.2 #10 | **对抗辩论模式** | 设计未落地 | P3 |
| C2 | §17.2 #12 | **Shadow Checkpoint**git 自动 commit | 设计未落地 | P3 |
| C3 | §17.2 #13 | **Skill 生命周期** | 设计未落地 | P3 |
| C4 | §17.1 #5 | **工具链集成** | PRD 差距 | P3 |
| C5 | §17.1 #6 | **经验闭环 IMPROVE** | PRD 差距 | P3 |
| C6 | §17.2 #16 | **per-provider 冷却** | 设计未落地 | P4 |
| C7 | §6.3.1 | **Gateway 内部 session lock 竞争**(已知限制,02 架构改造解决) | 已知限制 | P2 |
| C8 | §6.3.1 | **TOCTOU 竞态**L3a 检查和 CLI 获取 lock 之间的窗口期) | 已知限制 | P2 |
| D1 | HEARTBEAT | **v2.8 executor-prompt-design 漏洞**(3 个设计漏洞未修) | 设计暂停 | P3 |
| D2 | HEARTBEAT | **Pipeline 架构调研**(暂停,已废弃——不搞 Pipeline 框架) | 设计暂停 | ~~P3~~ 📦 已归档 |
| D3 | MEMORY | **M2 进程管理**(同步 vs 异步) | 待讨论 | P2 |
| D4 | MEMORY | **Agent 上下文膨胀** | 待讨论 | P2 |
### 21.2 T 阶段总览
| 阶段 | 名称 | 状态 | 核心目标 | 编号 |
|------|------|------|---------|------|
| **T1** | 文档对齐 + Bug 清理 | ✅ 已完成 | 状态机文档对齐 + BUG-22/OBS-25/OBS-26 修复 + 司马懿评审 | A3, A4, B10, B11 |
| **T2** | 持续指挥 + 动态规划 | 📋 待开始 | 庞统持续在线 + 活计划 + Daemon 退化 + BUG-7/BUG-8 | A1, A2, B8, B9 |
| **T3** | 主动汇报 + 需求探索触发 | 📋 待开始 | SSE 推 AI 摘要 + Daemon 自动触发需求探索 Skill | B1, B2 |
| **T4** | 审查体系完善 | 📋 待开始 | 方案审查自动流程 + 审查协议注册表 + verification_commands + 对抗辩论 | B3, B4, B5, C1 |
| **T5** | 上下文管理 | 📋 待开始 | prompt_templates + Prompt 进化 + Handoff + 知识注入 + CLI Schema + executor 漏洞 + 上下文膨胀 | B6, B7, D1, D4 |
| **T6** | 进程管理 M2 | 📋 待开始 | 同步进程管理方案 + Shadow Checkpoint | D3, C2 |
| **T7** | 经验闭环 + Skill 体系 | 📋 待开始 | Skill 生命周期 + IMPROVE 阶段 | C3, C5 |
| **T8** | 工具链 + 冷却 + Mail 统一 | 📋 最后做 | 工具链集成 + per-provider 冷却 + Mail 硬编码统一 | C4, C6, 话题1 |
### 21.3 各阶段详细规划
#### T1: 文档对齐 + Bug 清理 ✅ 已完成
**周期**: 2026-05-27 ~ 2026-05-28
**完成内容**
- ✅ architecture-v3.0.md 回溯性架构文档(20+ 章节,58KB)
- ✅ 7 条分类原则逐项审查
- ✅ A3: 状态机文档对齐(以代码为准更新)
- ✅ A4: `_generate_title()` 保留,标注未来替换成本地 LLM
- ✅ B10: P3 遗留 404/4xx 已修复(之前已修)
- ✅ B11: BUG-22/OBS-25/OBS-26 修复
- ✅ 广播认领从"未实现"纠正为"已实现"(司马懿评审纠正)
- ✅ 5 个设计矛盾逐个解决(§19.1~19.5)
- ✅ §17 待实现项分级(P1~P4)
- ✅ Gateway Watchdog 设计 + 部署
- ✅ 司马懿评审通过
#### T2: 持续指挥 + 动态规划 📋 待开始
**编号**: A1, A2, B8, B9
**核心目标**:庞统从"被动 delegate"变为"持续在线指挥官" + 先修已知 bug
**对应 PRD**:B2(编排层是 AI 指挥官)、C2(动态规划)、C3(持续指挥)
**关键变更**
1. 庞统持续指挥 session(当前只在 delegate 时被 spawn,无持续 session
2. 动态规划(活的执行方案,全程可调)
3. Daemon 角色退化(从调度器 → 投递员 + 看护人)(§6.5)
4. Agent 自主决策(读黑板 → 想 → 干 → 写回)
**涉及文件**: `src/daemon/ticker.py``src/daemon/dispatcher.py``src/daemon/router.py`
**前置条件**: T1 完成 ✅ + #02 Main Session Delegation 架构方案确认
**bug 修复**T2 前置):
- B8: BUG-7 planning 暂停失败 — 需在功能开发前修复
- B9: BUG-8 cancel→resume 空图完成 — 需在功能开发前修复
**已知限制**T2 需解决):
- C7: Gateway 内部 session lock 竞争 — 02 架构改造(统一 main session)根治
- C8: TOCTOU 竞态 — 同上,不再用 CLI spawn
**来源**: v2.8-direction-notes §一~§二 + §17 #2/#3
#### T3: 主动汇报 + 需求探索触发 📋 待开始
**编号**: B1, B2
**核心目标**:补齐 PRD 四相循环的 Phase 1 和 Phase 4
**对应 PRD**:B1(AI 帮人想清楚要什么)、B4(主动汇报)
**关键变更**
1. 需求探索自动触发:Skill 已有(requirement-clarification + requirements-analysis),缺 Daemon 自动触发机制
2. 主动汇报 AI 摘要:SSE 推送已有,但推送原始事件,不是 AI 自然语言摘要
**涉及文件**: `src/daemon/ticker.py``src/daemon/sse.py`、前端
**前置条件**: T2 完成
#### T4: 审查体系完善 📋 待开始
**编号**: B3, B4, B5, C1
**核心目标**:补齐质量门控的自动化环节
**对应 PRD**C4(质量门禁)、C9(安全红线)
**关键变更**
1. 方案审查自动流程:reviews 表支持 plan_review,但 Daemon 不自动触发
2. 审查协议注册表:review_protocols/ 目录创建
3. verification_commands:验证脚本层
4. Runaway Guardper-task max_ticks + 超限暂停告警(§14.3
5. 对抗辩论模式:high 风险任务自动 spawn 正反方
**涉及文件**: `src/daemon/ticker.py``src/daemon/review.py``review_protocols/`(新建)
**前置条件**: T2 完成
#### T5: 上下文管理 📋 待开始
**编号**: B6, B7, D1, D4
**核心目标**Agent 拥有自主决策的 prompt + 结构化交接 + 领域知识 + 解决上下文膨胀
**对应 PRD**:B3(共享意识)、C6(上下文管理)
**关键变更**
1. prompt_templates 角色模板:创建 executor.md / reviewer.md / planner.md(§10.4
2. Prompt 进化:从固定步骤 → 自主决策(§10.4)
3. Handoff 上下文:handoff.schema.json + bootstrap 增强(§10.5
4. 知识注入:spawner 新增 `_inject_wiki_knowledge()`(§10.6
5. CLI Schema 校验:schemas/ 目录
6. executor-prompt-design 3 个漏洞修复(D1
7. Agent 上下文膨胀解决方案(D4)
**涉及文件**: `src/daemon/spawner.py``src/daemon/bootstrap.py``schemas/`(新建)、`prompt_templates/`(新建)
**前置条件**: T2 完成(Prompt 进化依赖 Daemon 退化方向确定)
**来源**: v2.8-direction-notes §三(2)(3)(4) + §六
#### T6: 进程管理 M2 📋 待开始
**编号**: D3, C2
**核心目标**:解决 M2 进程管理问题 + Shadow Checkpoint
**关键变更**
1. M2 进程管理:当前 `subprocess.run()` 无法中途 kill,需讨论同步/异步方案(D3)
2. Shadow Checkpointgit 自动 commitC2
**前置条件**: T2 完成
**约束**: openclaw 不支持异步,需讨论替代方案(MEMORY 记录)
#### T7: 经验闭环 + Skill 体系 📋 待开始
**编号**: C3, C5
**核心目标**:完成经验沉淀闭环
**关键变更**
1. Skill 生命周期管理(draft→active→deprecated
2. 经验闭环 IMPROVE 阶段(使用后反馈/更新)
**前置条件**: T5 完成
#### T8: 工具链 + 冷却 + Mail 统一 📋 最后做
**编号**: C4, C6, 话题1
**核心目标**:工具链集成 + per-provider 冷却 + Mail 硬编码统一
**关键变更**
1. 工具链集成(lint/test/build
2. per-provider 冷却(Counter 扩展)
3. Mail 硬编码统一(§19.5,等稳定后再动)
**前置条件**: T2~T7 完成
**建议执行顺序**: T1 ✅ → T2(核心)→ T3 → T4 → T5 → T6 → T7 → T8(最后)
### 21.4 话题与 T 阶段映射
| 话题 | T 阶段 | 编号 | 状态 |
|------|--------|------|------|
| 话题1: Mail 硬编码独立 | **T8**(最后做) | C4, C6, 话题1 | ❌ 未实施 |
| 话题2: Prompt 进化 | **T5** | B6, D1 | ❌ 未实施 |
| 话题3: Handoff 上下文 | **T5** | B6 | ❌ 未实施 |
| 话题4: 知识注入 | **T5** | B6 | ❌ 未实施 |
| 话题5: Runaway Guard | **T4** | B5 | ⚠️ 部分实现 |
| 话题6: Daemon 退化 + Agent 进化 | **T2** | A1, A2 | ❌ 未实施 |
### 21.5 编号与 T 阶段完整映射
| 编号 | 问题 | T 阶段 | 状态 |
|------|------|--------|------|
| A1 | 动态规划 | T2 | ❌ |
| A2 | 持续指挥 | T2 | ❌ |
| A3 | 状态机矛盾 | T1 | ✅ 已解决 |
| A4 | _generate_title() 绕过 Gateway | T1 | ✅ 已保留 |
| B1 | 需求探索自动触发 | T3 | ❌ |
| B2 | 主动汇报 AI 摘要 | T3 | ❌ |
| B3 | 方案审查自动流程 | T4 | ❌ |
| B4 | 审查协议注册表 | T4 | ❌ |
| B5 | verification_commands | T4 | ❌ |
| B6 | prompt_templates 角色模板 | T5 | ❌ |
| B7 | CLI Schema 校验 | T5 | ❌ |
| B8 | BUG-7 planning 暂停失败 | T2 | ❌ |
| B9 | BUG-8 cancel→resume 空图 | T2 | ❌ |
| B10 | P3 遗留 404/4xx | T1 | ✅ 已修复 |
| B11 | BUG-22/OBS-25/OBS-26 | T1 | ✅ 已修复 |
| C1 | 对抗辩论模式 | T4 | ❌ |
| C2 | Shadow Checkpoint | T6 | ❌ |
| C3 | Skill 生命周期 | T7 | ❌ |
| C4 | 工具链集成 | T8 | ❌ |
| C5 | 经验闭环 IMPROVE | T7 | ❌ |
| C6 | per-provider 冷却 | T8 | ❌ |
| C7 | Gateway 内部 session lock 竞争 | T2 | ⚠️ 已知限制 |
| C8 | TOCTOU 竞态 | T2 | ⚠️ 已知限制 |
| D1 | executor-prompt-design 漏洞 | T5 | ❌ |
| D2 | Pipeline 架构调研 | — | 📦 已废弃 |
| D3 | M2 进程管理 | T6 | ❌ |
| D4 | Agent 上下文膨胀 | T5 | ❌ |
### 21.6 §17 待实现项与 T 阶段映射
| §17 # | 待实现项 | 编号 | T 阶段 |
|--------|---------|------|--------|
| 1 | 需求探索自动触发 | B1 | T3 |
| 2 | 动态规划 | A1 | T2 |
| 3 | 持续指挥 | A2 | T2 |
| 4 | 主动汇报 AI 摘要 | B2 | T3 |
| 5 | 工具链集成 | C4 | T8 |
| 6 | 经验闭环 IMPROVE | C5 | T7 |
| 8 | 方案审查自动流程 | B3 | T4 |
| 9 | 审查协议注册表 | B4 | T4 |
| 10 | 对抗辩论模式 | C1 | T4 |
| 11 | verification_commands | B5 | T4 |
| 12 | Shadow Checkpoint | C2 | T6 |
| 13 | Skill 生命周期 | C3 | T7 |
| 14 | prompt_templates 角色模板 | B6 | T5 |
| 15 | CLI Schema 校验 | B7 | T5 |
| 16 | per-provider 冷却 | C6 | T8 |
| — | Gateway 内部 session lock 竞争 | C7 | T2 (02 架构改造) |
| — | TOCTOU 竞态 | C8 | T2 (02 架构改造) |
---
## §22. Pipeline 强工作流设计(TODO
> 2026-06-04 新增。基于 #12 Pipeline 设计专题讨论确认的方向。本节所有内容均为 **待实现**,标注 TODO。
### 22.1 设计方向(2026-06-04 #12 讨论确认)
#### 两种模式
**自由模式(AI native**
- 不指定 task_type → 广播认领
- Agent 自主判断、自主认领、自主决定执行方式
- Agent 是决策主体
- 当前已实现
**Pipeline 强工作流(TODO**
- 指定 task_type → 确定性路由 + 状态机约束
- 系统控制流程、指定执行者、规定步骤顺序
- Agent 是执行主体,不是决策主体
- 不走 claim,直接 assign
- 引擎提示词需严格约束 Agent 行为边界,防止不可预料分支
#### Pipeline 灵活流转
- **顺序(sequence**A → B → C
- **条件分支(branch**review 通过 → donereview 拒绝 → working
- **退回(rollback**review 失败退回上一个 stage
- **循环重试(loop**max_retries 控制
#### 已确认的设计决策
| # | 决策 | 内容 |
|---|------|------|
| D1 | Pipeline vs 自由模式二选一 | task_type 决定走哪条路 |
| D2 | Pipeline 是强工作流,不可偏离 | Agent 必须按流程走 |
| D3 | @mention 在 Pipeline 模式下只做通知不改变执行者 | 流程控制权在系统 |
| D4 | task_type 默认 None(不指定 = 自由模式) | 向后兼容 |
| D5 | 前端下拉 + Chat 入口 | 用户选择 Pipeline 模式 |
#### 待深入设计的问题
1. **提示词约束**:强工作流下提示词模板如何约束 Agent 不产生不可预料分支
2. **模式共存**:自由模式和强工作流模式如何共存(同一系统、不同任务)
3. **差异化需求**:两种模式对 Spawner/Ticker/Router 的差异化需求
4. **排队处理**Pipeline 任务直接 assign 后 Agent 忙时的处理(Spawner 排队 vs 升级)
5. **错误处理**:强工作流下的错误处理(Agent 失败是流程回退,不是自主重试)
#### 相关设计文档
| 文档 | 说明 |
|------|------|
| `docs/design/12-pipeline-design.md` | Pipeline 设计专题 v2.1(已 approved |
| `docs/design/08-classify-outcome-optimization.md` | Classify Outcome v3.1 |
| `docs/design/09-rebuttal-and-goal-gate.md` | Rebuttal 流程 |
### 22.2 与现有架构的关系
- **Router(§8.1)**:当前只有确定性路由 + 广播认领两种模式。Pipeline 需要新增按 task_type 匹配 Pipeline 定义的路由模式
- **Ticker(§6.1**Pipeline 任务不走 `_broadcast_claim()`,走直接 assign + 状态机流转
- **Spawner(§6.3**Pipeline 任务的 spawn prompt 需严格约束行为边界,防止 Agent 偏离流程
- **状态机(§5.2**Pipeline 流转的 branch/rollback/loop 需要状态机支持更丰富的转换规则
### 22.3 实施建议
- 优先级:P2(核心架构增强,但不阻塞 T2 持续指挥)
- 前置条件:T2 完成后再启动(避免与 Daemon 退化方向冲突)
- 建议阶段:T4 审查体系完善之后,或独立为 T4.5
- 里程碑:先实现单一顺序 Pipeline(A→B→C),再扩展条件分支