# AI Native DevOps Platform 架构设计 v3.0 **版本**: v3.0(PRD 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 --session-id ┌──────────────────────────▼──────────────────────────────────┐ │ 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. **L3a(lock 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) | 自主决策者(读黑板→想→干→写回) | | 谁决定执行路径 | Daemon(if/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 调用。当前前端已支持传 title,LLM 生成只是 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 Handoff(Agent 主动写交接文档传递上下文) **涉及文件**: `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_by,must_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。当前前端已支持传 title,LLM 只是 fallback,不影响正常使用。 ### 19.4 续杯设计 ✅(已验证一致) **spawner-monitor-design v2.0**: 续杯只有 A2/A3(Gateway timeout)触发。 **实际 spawner 代码**: `_handle_exit` 中 `cls["should_retry"]` 为 True 时才走 `_do_retry`,注释明确 "只有 A2/A3(gateway_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 Guard:per-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 Checkpoint:git 自动 commit(C2) **前置条件**: 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 通过 → done,review 拒绝 → 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),再扩展条件分支