# 课题3 设计方案：挑战/评审体系 + 质量门控结构化

**作者**: 庞统士元
**日期**: 2026-05-15
**状态**: 方案待确认
**前置**: 课题1（AI决策者参与）、课题2（事件驱动+上下文传递）已结题

---

## 1. 设计目标

课题1已定义了"谁来判断"（双轨制：Daemon系统保护 + Coordinator AI决策）和"判断什么"（must_haves三件套、幻觉门控、Scope Guard）。课题2定义了"怎么触发判断"（Tick+Inbox事件驱动、Handoff Comment无缝接手）。

**课题3要解决的问题是：判断的结果怎么记录、怎么协商、怎么流转。**

具体来说：
1. 评审结果怎么结构化存储（不是散落在 comments 里的自然语言）
2. 挑战/评审的协商流程怎么设计（几轮、升级条件、对抗模式）
3. 评审体系和现有状态机（pending→working→review→done）怎么对齐

## 2. v1.0 三层体系的问题

| 问题 | v1.0 做法 | 根因 |
|------|----------|------|
| PAV自律形同虚设 | Plan→Act→Verify 靠 Skill 文本约束 | Skill 是"菜单"不是"触发器"，Agent 可忽略 |
| 每个节点都审过重 | 司马懿审所有节点 | 没有分级，简单任务和复杂任务同一个审查标准 |
| 方案阶段没审查 | 只审产出不审方案 | 编码前的设计方案没有独立审查 |
| 评审结果不结构化 | 司马懿写自然语言评论 | 无法机器判断"通过还是没通过"，只能人读 |
| 司马懿角色重叠 | 节点审一次 + 终审一次 | 重复劳动 |

## 3. 设计决策

### D3-1：评审体系由三层改为"分级 + 流水线"

> **参考实践**：
> - **superpowers**：串行双审（spec reviewer → code quality reviewer），先审方案再审代码
> - **TradingAgents**：多空对抗辩论（Bull vs Bear → Research Manager 裁决）
> - **OpenAI Agent SDK**：Guardrail 是 tripwire（检测到违规立即中断，不是建议）
> - **Hermes v0.13**：Comment 的 metadata JSON 承载结构化数据（changed_files / tests_run / diff_path）
> - **v1.0 PRD**：review_result JSON 结构（verdict + issues + round + max_rounds）
> - **GitHub PR Review**：APPROVE / REQUEST_CHANGES / COMMENT 三种明确 verdict

**核心思路**：不搞三层并行，而是每个任务按风险等级走不同的审查流水线。

| 任务风险等级 | 流水线 | 方案审查 | 产出审查 | 审查模式 | 最大轮次 |
|------------|--------|---------|---------|---------|---------|
| **high**（部署/策略/资金） | 三阶段 | ✅ 独立审查 | ✅ 独立审查 + Guardrail | 对抗辩论 | 5 |
| **standard**（编码/设计） | 二阶段 | ✅ 方案过挑战 | ✅ 产出过挑战 | 单审 | 3 |
| **low**（文档/格式化/搬运） | 一阶段 | ❌ 跳过 | ⚡ Guardrail 自动检查 | 自动 | 0 |
| **research**（调研/分析） | 一阶段 | ❌ 跳过 | ✅ 庞统确认方向 | 单审 | 2 |

**和课题1的分级审查矩阵对齐**：课题1的 §9.5 已定义了四级风险等级和审查深度，课题3 补充的是每个等级内部的具体流程。

### D3-2：评审三阶段流水线（high/standard 任务）

> **参考实践**：
> - **superpowers**：implementer → spec reviewer（必须通过） → code quality reviewer
> - **TradingAgents**：多空辩论 + Manager 裁决，用 `add_conditional_edges` 实现
> - **OpenAI Agent SDK**：OutputGuardrail 是并行运行的轻量 AI Agent，不是 if-else 规则

**阶段 1：方案审查（Plan Review）**——只对 high/standard 任务

```
执行者提交方案（scope_declaration）到黑板 decisions 表
    ↓
挑战者审查方案
    ├── high：对抗辩论（正方 vs 反方 → 庞统裁决）
    └── standard：单审（指定挑战者，默认司马懿）
    ↓
通过 → 进入执行阶段
未通过 → 协商修改（最多 max_rounds 轮）
    └── 超轮次 → 升级用户
```

方案审查和课题1的 Scope Guard 关系：
- Scope Guard（L2 sub 异步检查）是吹哨人——发现偏离写 observation
- 方案审查（L3 Agent 正式审查）是正式评审——通过/打回有 verdict
- 两者互补：Scope Guard 是过程中的软检查，方案审查是阶段门

**阶段 2：执行 + Guardrail 自动检查**——所有任务

```
执行者按方案执行
    ↓
每次写 output 时，Daemon 自动触发 Guardrail
    ├── L1 机械检查（文件存在、JSON 格式、字段非空）→ 不通过直接打回
    ├── L2 轻量 AI 检查（Schema 校验、artifacts 路径验证）→ 不通过写 observation
    └── L3 安全红线（tripwire：如直接操作生产环境）→ 立即中断
    ↓
Guardrail 通过 → 进入产出审查
Guardrail 不通过 → 自动打回（tripwire 直接 block）
```

**阶段 3：产出审查（Output Review）**——high/standard 任务

```
执行者提交产出到黑板 outputs 表
    ↓
挑战者审查产出（质量/完整性/与方案一致性）
    ↓
评审结果结构化记录到 reviews 表
    ↓
通过 → status: review → done
未通过 → status: review → working（打回重做）
    └── 协商在 comments 表讨论
    └── 超轮次 → 升级用户
```

### D3-3：评审结果结构化存储（reviews 表）

> **参考实践**：
> - **Hermes**：Comment 的 metadata JSON 承载结构化数据
> - **SWE-agent**：Trajectory 线性追加，不修改历史
> - **v1.0 PRD**：review_result JSON（verdict + issues + round）
> - **GitHub PR Review**：APPROVE / REQUEST_CHANGES / COMMENT 三种 verdict
> - **Control Center**：artifacts 按 stage 组织，支持阶段回退

**设计原则**：
1. **追加写入不修改历史**（SWE-agent 模式）——每轮评审是新记录
2. **黑板索引 + 文件详情**（课题2 原则）——黑板存摘要，文件存详情
3. **结构化 verdict**（GitHub PR Review 模式）——枚举值，不是自然语言
4. **关联产出物**（Control Center 模式）——review 关联到具体 output

```sql
-- ===== 评审结果表 =====
CREATE TABLE IF NOT EXISTS reviews (
    id TEXT PRIMARY KEY,                     -- rev-001
    task_id TEXT NOT NULL,
    output_id TEXT,                          -- 关联产出物（outputs 表）
    reviewer TEXT NOT NULL,                  -- 审查者 agent id 或 'system'
    review_type TEXT NOT NULL,
    CHECK (review_type IN ('plan_review', 'output_review', 'guardrail', 'final_review')),

    -- 评审结论（必须是枚举）
    verdict TEXT NOT NULL,
    CHECK (verdict IN ('approved', 'rejected', 'needs_revision')),

    -- 信心度（可选）
    confidence REAL,                         -- 0.0-1.0

    -- 协商轮次
    round INTEGER NOT NULL DEFAULT 1,
    max_rounds INTEGER NOT NULL DEFAULT 3,
    consensus_reached BOOLEAN DEFAULT FALSE,

    -- 摘要（黑板索引）
    summary TEXT NOT NULL,                   -- 一句话结论（人可读）

    -- 详情路径
    detail_path TEXT,                        -- 完整评审报告文件

    created_at TEXT NOT NULL DEFAULT (datetime('now')),

    FOREIGN KEY (task_id) REFERENCES tasks(id),
    FOREIGN KEY (output_id) REFERENCES outputs(id)
);

CREATE INDEX IF NOT EXISTS idx_reviews_task ON reviews(task_id);
CREATE INDEX IF NOT EXISTS idx_reviews_output ON reviews(output_id);
```

**评审详情文件**（detail_path 指向）：

```json
{
  "review_id": "rev-001",
  "task_id": "task-001",
  "output_id": "out-001",
  "reviewer": "simayi-challenger",
  "review_type": "output_review",
  "verdict": "needs_revision",
  "confidence": 0.65,
  "round": 1,
  "max_rounds": 3,
  "summary": "代码逻辑正确但缺少错误处理和单元测试",
  "issues": [
    {
      "id": "iss-001",
      "severity": "critical",
      "category": "correctness",
      "location": "src/trading.py:42",
      "description": "未处理网络超时异常",
      "suggestion": "添加 try-except 包装，设置 30s 超时"
    }
  ],
  "positives": ["代码结构清晰，职责分离做得好"],
  "metadata": {
    "files_reviewed": ["src/trading.py", "src/utils.py"],
    "total_lines_reviewed": 150
  }
}
```

### D3-4：Guardrail 检查结果也入 reviews 表

> **参考实践**：
> - **OpenAI Agent SDK**：Guardrail 的 tripwire_triggered 是结构化输出
> - **Hermes 幻觉门控**：系统验证产出是否真实存在

Guardrail 自动检查结果存入 reviews 表（`reviewer='system'`, `review_type='guardrail'`）：

```json
{
  "review_id": "rev-auto-001",
  "reviewer": "system",
  "review_type": "guardrail",
  "verdict": "rejected",
  "summary": "Guardrail 检查失败：产出文件不存在",
  "issues": [
    {
      "severity": "blocking",
      "description": "产出文件不存在: output.md"
    }
  ]
}
```

**和课题1的 Guardrail 吹哨人机制对齐**：
- L1 机械检查失败 → 直接入 reviews 表（verdict=rejected）+ 打回
- L2 轻量 AI 检查发现问题 → 写 observation（课题1设计）+ 入 reviews 表（verdict=needs_revision）
- L3 tripwire → 直接入 reviews 表（verdict=rejected）+ block 任务

### D3-5：对抗辩论模式（high 风险任务）

> **参考实践**：
> - **TradingAgents**：Bull Researcher vs Bear Researcher → Research Manager 裁决
> - **MetaGPT**：Engineer Agent 隐式 supervisor，按 SOP 产出
> - **oh-my-claudecode Critic**：Critic 被禁止 Write/Edit 工具，只能读和评论

**high 风险任务的方案审查和产出审查都走对抗模式**：

```
方案审查（对抗模式）：
  正方（执行者）：写 scope_declaration，论证方案可行性
  反方（挑战者池中的一人）：找方案漏洞、风险、遗漏
      ↓
  庞统裁决：综合双方观点，做最终判断
      ├── 认可正方 → 方案通过
      ├── 认可反方 → 方案打回
      └── 综合意见 → 要求修改后重新辩论
```

**挑战者池**：不是固定司马懿一个人，而是按任务类型选择：
- 编码任务 → 司马懿
- 风控任务 → 关羽
- 数据任务 → 赵云（数据质量视角）
- 部署任务 → 姜维

庞统在黑板上创建任务时指定 reviewer（`assigned_by` 字段已有）。

### D3-6：协商流程与状态机对齐

> **参考实践**：
> - **superpowers**：implementer 报告四种状态（task_completed / task_completed_with_notes / task_blocked / task_failed）
> - **Hermes**：block with reason 前缀约定（review-required: / blocked-by:）
> - **v1.0 PRD**：三轮协商上限，超轮次升级用户

**现有状态机**：`pending → claimed → working → review → done`

**和评审流水线的对齐**：

```
pending → claimed → working
                        ↓
                    [方案审查]（high/standard）
                        ├── approved → 继续 working
                        └── needs_revision → 继续 working（修改方案）
                        └── 超轮次 → 升级用户
                        ↓
                    [执行 + Guardrail]
                        ├── guardrail rejected → back to working（自动打回）
                        └── guardrail passed → 继续
                        ↓
                    写 output → status: review
                        ↓
                    [产出审查]（high/standard）
                        ├── approved → status: done
                        ├── needs_revision → status: working（协商在 comments）
                        └── rejected → status: working（打回重做）
                        └── 超轮次 → 升级用户

low 风险任务：working → [Guardrail 自动检查] → done（跳过 review 状态）
research 任务：working → [庞统确认] → review → done
```

**新状态机扩展**（在现有 8 状态基础上，不增加新状态）：

| 状态转换 | 触发条件 | 对应阶段 |
|---------|---------|---------|
| working → working | 方案审查 needs_revision | 阶段 1 |
| working → review | 写 output + Guardrail 通过 | 阶段 2→3 |
| working → working | Guardrail rejected（自动打回） | 阶段 2 |
| review → done | 产出审查 approved | 阶段 3 |
| review → working | 产出审查 needs_revision | 阶段 3 |
| review → blocked | 超轮次升级 | 阶段 3 |

### D3-7：comments 表和 reviews 表的职责分离

| 表 | 职责 | 内容类型 | verdict |
|---|------|---------|---------|
| **comments** | 讨论、@mention、协商过程 | 自然语言 | ❌ 无 |
| **reviews** | 正式评审结论 | 结构化 JSON | ✅ 必须有 |

评审协商过程（"这里有个问题，建议这样改"）写在 comments。
评审结论（"通过" / "不通过，原因见 issues"）写在 reviews。

两者关联：reviews.detail_path 指向的完整报告可以引用 comments 中的讨论。

### D3-8：声明式 Guardrail 配置（YAML）

> **参考实践**：
> - **OpenAI Agent SDK**：`@output_guardrail` 装饰器声明检查函数
> - **v1.0 M4 Guard**：entry/exit guard + skill 化检查逻辑
> - **SonarQube / CodeClimate**：rule_id 关联可查规则文档

```yaml
# guardrails.yaml
#
# L1 check 用 assert 字段（Python 表达式，Daemon eval 执行）
# L2 check 用 prompt 字段（传给 subagent 的检查指令）

task_types:
  coding:
    output_guardrails:
      - name: file_exists
        assert: "len(output.get('files', [])) > 0"
        severity: blocking
        layer: L1
      - name: json_valid
        assert: "output.get('json_schema_valid', False) == True"
        severity: blocking
        layer: L1
      - name: artifacts_exist
        assert: "all(os.path.exists(p) for p in output.get('artifacts_paths', []))"
        severity: blocking
        layer: L1
      - name: scope_alignment
        prompt: "Compare the agent's scope_declaration against task truths. Check: is every truth covered? Are there deviations not declared?"
        severity: warning
        layer: L2
    output_review:
      required: true
      mode: single_reviewer
      max_rounds: 3

  deploy:
    plan_review:
      required: true
      mode: debate
      max_rounds: 5
    output_guardrails:
      - name: no_direct_production
        assert: "output.get('target_env') != 'production'"
        severity: tripwire
        layer: L1
      - name: rollback_plan_exists
        assert: "output.get('rollback_plan') is not None"
        severity: blocking
        layer: L1
    output_review:
      required: true
      mode: debate
      max_rounds: 5

  data:
    output_guardrails:
      - name: format_check
        assert: "output.get('format') in ['csv', 'parquet', 'json']"
        severity: blocking
        layer: L1
    output_review:
      required: false

  research:
    output_review:
      required: true
      reviewer: "pangtong-fujunshi"   # 庞统确认方向
      mode: single_reviewer
      max_rounds: 2
```

## 4. 评审记录与 Handoff Comment 的关系

> **对齐课题2设计**

Handoff Comment（课题2）是 Agent 结束时写的交接信息。评审记录（课题3）是挑战者写的审查结论。

两者在黑板上的关系：

```
Agent A 完成产出
  → 写 Handoff Comment（comments 表，type=handoff）
  → 写 output（outputs 表）
  → 通知 Daemon（inbox JSONL）
  ↓
Daemon 触发 Guardrail 自动检查
  → 结果写入 reviews 表（reviewer='system', review_type='guardrail'）
  → 通过 → 进入产出审查
  → 不通过 → 打回
  ↓
Daemon spawn 挑战者
  → 挑战者读黑板：L1 含 Agent A 的 Handoff Comment + output summary
  → 挑战者做审查
  → 写 review（reviews 表，verdict + summary + detail_path）
  → 写 comment（comments 表，协商讨论）
  → 通过 → status: done
  → 不通过 → status: working + Agent A 被 spawn 重做
```

下一个 Agent（如果需要）的 L1 消息中包含：
1. Agent A 的 Handoff Comment（最近3条评论之一）
2. 挑战者的 review summary（reviews 表最新一条）
3. 协商过程的 comments（L2 按需读取）

### D3-9：审查协议注册表（Review Protocol Registry）

> **参考实践**：
> - **superpowers**：三个独立 prompt 文件——`implementer-prompt.md`、`spec-reviewer-prompt.md`、`code-quality-reviewer-prompt.md`，每个角色有专属模板，不是笼统的"请审查"
> - **oh-my-claudecode Critic**：Investigation Protocol 分 Phase 执行（预判→验证→多视角→缺口分析→自审），不同 artifact type 自动切换视角（代码→安全/新人/运维，方案→执行者/利益相关者/怀疑论者）
> - **superpowers spec-reviewer**：prompt 注入对抗性指令——"DO NOT trust the report. Read the actual code.""Compare to requirements line by line."

**问题**：审查者不知道自己该审什么，容易陷入局部审查（编码规范、编译通过），漏掉本质问题（需求一致性、语义正确性）。或者被挑战后一律照改，不加思考。

**根因**：审查指令是笼统的"请审查"，审查者靠"自觉"决定审什么。Skill 是软引导，可看可不看。

**方案**：审查协议是代码注入的，不是靠 Agent 自己去找的。Daemon spawn 审查者时，根据任务类型 + 审查类型动态加载协议模板，注入到 bootstrap 消息中。

```
review_protocols/
├── plan_review.yaml          # 方案审查协议
├── output_review.yaml        # 产出审查协议
├── guardrail_l2.yaml         # L2 轻量AI检查协议
└── analysis_review.yaml      # 分析/调研审查协议
```

每个协议文件定义四个维度：

**维度1：审查维度（审什么）**

```yaml
# review_protocols/output_review.yaml（示例片段）
dimensions:
  - id: requirement_traceability
    description: "每个 must_have truth 是否被覆盖"
    weight: critical
    method: "逐条比对 truths → 产出代码/文件"
    
  - id: scope_alignment
    description: "产出是否与 scope_declaration 一致"
    weight: critical
    method: "对比 decisions.scope_declaration vs 实际产出"
    
  - id: correctness
    description: "逻辑是否正确"
    weight: major
    method: "追踪执行路径，验证关键逻辑"
    
  - id: completeness
    description: "是否有遗漏"
    weight: major
    method: "缺口分析：什么缺失了？什么假设未被验证？"
    
  - id: constraint_compliance
    description: "是否遵守约束"
    weight: major  
    method: "逐条检查 tasks.constraints"
```

**维度2：审查方法（怎么审）**——参考 oh-my-claudecode Critic 的 Investigation Protocol

```yaml
investigation_protocol:
  phases:
    - name: pre_commitment
      instruction: >
        先不读产出，凭领域经验预测3-5个最可能出问题的点。
        写下预测。然后逐个验证。这迫使主动搜索而非被动阅读。
      
    - name: verification
      instruction: >
        读实际产出（不是报告），逐条验证每个 truth。
        提取所有文件引用、函数名、API 调用，逐一对照源码验证。
        模拟执行每个步骤，不只读文字描述。
      
    - name: multi_perspective
      instruction: >
        从不同角色看这份产出：
        - 安全视角：什么信任边界被跨越？什么输入没校验？
        - 新人视角：不熟悉代码的人能理解吗？什么上下文被假设但没说明？
        - 运维视角：规模化后怎样？依赖失败时怎样？爆炸半径多大？
      
    - name: gap_analysis
      instruction: >
        不只看"什么有问题"，还看"什么缺失了"。
        问：什么会破坏这个？什么边界情况没处理？什么假设可能是错的？
      
    - name: self_audit
      instruction: >
        给自己的每个 finding 打 confidence（HIGH/MEDIUM/LOW）。
        LOW confidence → 降级为 Open Question。
        "作者能立刻反驳吗？"如果能 → 降级。
        "这是真正的缺陷还是风格偏好？"如果是偏好 → 降级。
```

不同审查类型用不同的 multi_perspective 视角集（参考 Critic 的代码视角 vs 方案视角分离）：

| 审查类型 | 多视角集合 |
|---------|----------|
| `output_review`（代码产出） | 安全 / 新人 / 运维 |
| `plan_review`（方案） | 执行者 / 利益相关者 / 怀疑论者 |
| `analysis_review`（调研分析） | 领域专家 / 实践者 / 反方辩手 |
| `guardrail_l2`（轻量检查） | 无多视角（单一维度快速检查） |

**维度3：对抗性指令（防止走过场）**——参考 superpowers spec-reviewer 的"DO NOT trust"指令

```yaml
adversarial_instructions:
  - "DO NOT trust the implementer's report. Read the actual code/files."
  - "If something looks correct on the surface, verify it works in context."
  - "Not just what's wrong — also check what's MISSING."
  - "Accept findings only with evidence (file:line or specific quote). No evidence = opinion."
  - "If you find 1 CRITICAL or 3+ MAJOR issues, escalate to adversarial mode: actively hunt for more problems, challenge every design decision, expand scope to adjacent code."
  - "Also check for EXTRA/UNNEEDED work that wasn't requested."
```

**维度4：输出格式**

```yaml
output_schema: "schemas/review-output.schema.json"
verdict_options: ["approved", "rejected", "needs_revision"]

required_fields:
  - verdict
  - summary
  - issues[] (each with severity, description, evidence)
  - confidence (0.0-1.0)
```

**Daemon 拼接逻辑**：

```python
def build_reviewer_bootstrap(task, review_type):
    # 1. 加载协议模板
    protocol = load_protocol(f"review_protocols/{review_type}.yaml")
    
    # 2. 注入任务上下文（ truths, constraints, scope_declaration）
    protocol.inject_context(task)
    
    # 3. 拼接成 L1 bootstrap 消息
    # 审查者收到的消息 = 角色定义 + 审查协议 + 任务上下文 + 必读材料
    return format_reviewer_bootstrap(protocol, task)
```

**防止"一律照改"——反驳权（Rebuttal Phase）**：

审查不是单向的。但不是每次都触发反驳——有跳过条件：

**跳过条件**（不需 spawn 反驳）：
- 审查者 verdict=approved → 直接 done，跳过 rebuttal
- 审查者 verdict=needs_revision，但 issues 全是 minor severity → 执行者自然在 comments 接受并修改，不 spawn 反驳

**触发条件**（spawn 反驳）：
- 审查者 verdict=needs_revision，且 issues 中有 critical 或 major severity
- 审查者 verdict=rejected

```
审查者提交 review
    ↓
verdict=approved → 直接 done（跳过 rebuttal）
verdict=needs_revision 且只有 minor → 执行者直接修改（跳过 rebuttal）
verdict=needs_revision 且有 critical/major → spawn 反驳
    ↓
Daemon spawn 原执行者，注入反驳指令：
    "你收到了一份审查意见。对每个 issue，你必须明确表态：
     ACCEPT（接受并修改）/ REJECT（拒绝，说明为什么）/ PARTIAL（部分接受）
     不允许全部接受不加思考。"
    ↓
执行者 response 写入 comments 表
    ↓
如果是 REJECT → Daemon spawn 审查者看 response → 继续协商
如果全部 ACCEPT → 修改后重新提交 → 审查者 re-review
```

### D3-10：OpenClaw 集成——Full Agent vs Subagent vs Daemon 直接执行

> **参考实践**：
> - **superpowers**：Implementer / Spec Reviewer / Code Quality Reviewer 都是 Task tool dispatch 的 subagent，但各自有独立的 prompt 模板和模型选择
> - **oh-my-claudecode**：Critic 被禁止 Write/Edit 工具（disallowedTools），是角色隔离而非进程隔离
> - **open-multi-agent**：TaskQueue 维护 agent pool，scheduler 按 capability-match 分配任务

**问题**：什么任务需要完整的 Agent 身份（SOUL/IDENTITY/MEMORY），什么任务只需要无身份的 AI Worker？

**判据：五个问题**

| 问题 | 走 Full Agent | 走 Subagent | Daemon 直接执行 |
|------|-------------|-----------|--------------|
| 需要独立身份/人格吗？ | ✅ 司马懿的"质量守门人" | ❌ | ❌ |
| 需要 Agent 专属工具吗？ | ✅ 关羽的风控工具 | ❌ 通用 exec/read 就够 | 不需要 AI |
| 任务复杂度 | 编码、审查、调研、决策 | 单一检查、快速评估 | 格式校验、文件存在检查 |
| 需要写黑板吗？ | ✅ 写 review/output/decision | ❌ 只返回 pass/fail | 只改状态 |
| 需要多轮交互吗？ | ✅ 协商、反驳、辩论 | ❌ 一次性的 | 一次性的 |

**对应到我们的场景**：

| 场景 | 走什么 | OpenClaw API | 理由 |
|------|--------|-------------|------|
| 张飞编码 | Full Agent | `openclaw agent --agent zhangfei-dev` | 需要身份、编码工具 |
| 司马懿产出审查 | Full Agent | `openclaw agent --agent simayi-challenger` | 需要质量守门人角色、多轮协商 |
| 执行者反驳审查 | Full Agent（原 Agent） | `openclaw agent --agent <原执行者>` | 需要原执行者的身份和上下文 |
| 庞统任务规划 | Full Agent | `openclaw agent --agent pangtong-fujunshi` | 需要副军师角色、决策能力 |
| 庞统冲突裁决 | Full Agent（隔离 session） | `openclaw agent --agent pangtong-fujunshi --session-id <new>` | 避免主 session 上下文膨胀 |
| 赵云数据下载 | Full Agent | `openclaw agent --agent zhaoyun-data` | 需要数据工具、NAS 操作 |
| 姜维部署 | Full Agent | `openclaw agent --agent jiangwei-infra` | 需要 Docker/PM2 工具 |
| L2 Guardrail AI 检查 | Subagent | `sessions_spawn(task=...)` | 单一检查、不需要身份 |
| Scope Guard 异步检查 | Subagent | `sessions_spawn(task=...)` | 轻量、一次性 |
| L1 机械校验（文件存在/JSON格式） | **不走 AI** | Daemon 直接执行 | 纯机械操作，不需要 AI |

**简化规则**：黑板上有名字的角色（庞统/司马懿/张飞/关羽/赵云/姜维）走 Full Agent。没有名字的一次性检查走 Subagent。纯机械检查 Daemon 自己做。

**OpenClaw spawn 具体实现**：

```python
def spawn_agent(agent_id, task_id, mandate):
    """Spawn Full Agent（有身份、有专属工具）"""
    session_id = f"moziplus-{task_id}-{agent_id}-{uuid4().hex[:8]}"
    bootstrap_msg = format_mandate_message(mandate)
    
    subprocess.run([
        "openclaw", "agent",
        "--agent", agent_id,
        "--session-id", session_id,
        "--message", bootstrap_msg
    ], capture_output=True, text=True)
    
    # 记录到黑板 events 表
    blackboard.execute(
        "INSERT INTO events (task_id, event_type, data) VALUES (?, 'agent_spawned', ?)",
        task_id, json.dumps({"session_id": session_id, "agent_id": agent_id})
    )

def spawn_subagent(task_id, task_description, context=None):
    """Spawn Subagent（无身份、通用工具、一次性）"""
    # 通过 OpenClaw API spawn 轻量 worker
    # 返回结果直接处理，不写入黑板 reviews 表
    # 适用于 L2 Guardrail、Scope Guard 等轻量检查
    pass
```

**庞统主 session 的隔离策略**：

庞统主 session 做轻量调度（L1 构建、状态检查、黑板 tick 处理）。复杂的任务拆解和裁决 spawn 一个 pangtong-fujunshi 的隔离 session，避免主 session 上下文膨胀（课题2 D2-6：不需要 Auto-compact，但庞统是唯一可能有累积的 session）。

---

## 5. 遗留 TODO

| # | 待解决事项 | 归属 | 说明 |
|---|----------|------|------|
| ~~T3-1~~ | ~~reviews 表的 CLI 命令~~ | ~~Phase 2~~ | ✅ 方案已定，开发实现 |
| ~~T3-2~~ | ~~Guardrail YAML 解析 + 执行引擎~~ | ~~Phase 2~~ | ✅ 方案已定，开发实现 |
| ~~T3-3~~ | ~~对抗辩论模式的具体黑板协议~~ | ~~Phase 3~~ | ✅ 方案已定（见 §5.1），仅在用户明确要求时启用 |
| ~~T3-4~~ | ~~挑战者池的选择策略~~ | ~~Phase 2~~ | ✅ 方案已定，开发实现 |
| ~~T3-5~~ | ~~confidence 低于阈值自动升级~~ | ~~Phase 2~~ | ✅ 方案已定，开发实现 |
| ~~T3-6~~ | ~~评审详情文件的 Schema 定义~~ | ~~Phase 2~~ | ✅ 方案已定（见 §5.2），待司马懿评审确认 |
| ~~T3-7~~ | ~~low 风险任务 Guardrail 自动通过~~ | ~~Phase 2~~ | ✅ 方案已定，开发实现 |
| ~~T3-8~~ | ~~Review Protocol 模板文件编写~~ | ~~Phase 2~~ | ✅ 方案已定，开发实现 |
| ~~T3-9~~ | ~~反驳权 Daemon 流控~~ | ~~Phase 2~~ | ✅ 方案已定（见 §5.3），轮次上限兜底不设超时 |
| ~~T3-10~~ | ~~Agent 调度判据~~ | ~~Phase 2~~ | ✅ 方案已定（见 §5.4），配置表驱动非 AI 判断 |

### 5.1 对抗辩论黑板协议（T3-3 方案）

> **触发条件**：仅在用户明确在任务意图中包含"辩论"等字样时启用。大多数任务走标准挑战机制（单审 + 反驳权）足够。

**调研来源**：TradingAgents（Bull vs Bear → Manager 裁决）、学术界 MAD（critic/defender/judge 三角色、稳定性检测早停）、claude-goal（none/adversarial/double 三级）。

**三角色 × 最多 5 轮 × 2 种结束条件**：

- **正方（Proponent）**= 执行者
- **反方（Opponent）**= 挑战者池按任务类型选择
- **裁决者（Judge）**= 庞统（隔离 session）

**黑板交互格式**：

每个参与者用 comments 表写入，按类型区分：
- `comment_type = "debate_argument"` → 正方/反方论点
- `comment_type = "debate_rebuttal"` → 反驳
- `comment_type = "debate_judgment"` → 庞统裁决

每条 comment 的结构：
```json
{
  "role": "proponent | opponent | judge",
  "round": 1-5,
  "claims": [
    {"point": "...", "evidence": "文件路径/行号/数据", "severity": "critical|major|minor"}
  ],
  "concession": ["我接受的观点..."],
  "stance": "hold | yield | partial"
}
```

**流程**：

```
Round 1: 正方写 scope_declaration + arguments → 反方读后写反驳
Round 2+: 正方回应反驳 → 反方回应
每轮结束后 Daemon 检查结束条件
```

**结束条件**（任一满足即停）：

1. **达成共识**：一方 stance=yield 或双方 stance=partial
2. **轮次耗尽**：达到 max_rounds（默认 5）
3. **稳定性检测**：连续 2 轮无新论点（claims 无变化）→ 提前终止

达成共识 → 按共识结论执行。轮次耗尽/稳定性 → 庞统裁决。

庞统裁决输出：写入 reviews 表（verdict + summary + detail_path），verdict = approved | rejected | needs_revision。

**reviews 表变更**：新增 `debate_context` JSON 字段（存辩论参与者和轮次数）。

### 5.2 评审详情文件 Schema（T3-6 方案）

> **待司马懿评审确认。**

**调研来源**：SARIF（Static Analysis Results Interchange Format）result 结构、GitHub PR Review、Hermes comment metadata JSON。

**Schema**（`{task_id}/reviews/{review_id}.json`）：

```json
{
  "$schema": "review-detail-v1",
  "review_id": "rev-001",
  "task_id": "task-001",
  "reviewer": "simayi-challenger",
  "review_type": "output_review",
  "verdict": "approved",
  "confidence": 0.85,
  "round": 1,

  "summary": "一句话结论",

  "issues": [
    {
      "id": "iss-1",
      "status": "open|accepted|rejected|deferred",
      "severity": "critical|major|minor|info",
      "category": "correctness|security|performance|style|scope_deviation|architecture|robustness",
      "location": {
        "file": "src/strategy.py",
        "line_start": 42,
        "line_end": 55,
        "context": "def calculate_signal(df):\n    ..."
      },
      "title": "简短描述",
      "description": "详细说明",
      "evidence": "代码片段或引用",
      "suggestion": "修复建议",
      "remediation_effort": "low|medium|high"
    }
  ],

  "evidence": [
    {
      "type": "file_content",
      "path": "src/strategy.py",
      "relevant_lines": [42, 43, 44]
    },
    {
      "type": "command_output",
      "command": "pytest tests/ -x",
      "exit_code": 1,
      "output": "失败信息..."
    }
  ],

  "positives": ["做得好的地方"],

  "meta": {
    "review_protocol": "output_review",
    "files_reviewed": 3,
    "model_used": "zhipu/glm-5.1"
  }
}
```

**SARIF 借鉴**：issues 数组结构（severity + location + message）是 SARIF result 核心字段，但我们简化了——不需要 SARIF 的完整 taxonomy 和 rule metadata，我们的场景是 Agent 审查而非静态分析工具。

### 5.3 反驳权 Daemon 流控（T3-9 方案）

**本质问题**：审查者和执行者意见不一致时，Daemon 怎么管理协商过程。

**调研来源**：TradingAgents（Bull/Bear → Manager 裁决）、claude-goal（double 审计）、superpowers（verify→fix loop）。

**触发条件**（不是所有 review 都触发）：

- review verdict=needs_revision，且 issues 中有 critical/major severity → 触发反驳
- review verdict=rejected → 触发反驳
- review verdict=approved → 不触发，直接 done
- review verdict=needs_revision，但只有 minor → 不触发，执行者直接改

**流程**：

```
审查者提交 review（verdict=needs_revision/rejected）
    ↓
Daemon tick 检测到 review → 检查 issues severity → 判定需要反驳
    ↓
Daemon spawn 原执行者，注入：
  "你收到了一份审查意见。对每个 issue，你必须表态：
   ACCEPT / REJECT（说明理由） / PARTIAL（说明接受哪些）
   不允许全部接受不加思考。"
    ↓
执行者写入 comments（comment_type="rebuttal"）
    ↓
Daemon 检查 rebuttal 结果：
  │
  ├── 全部 ACCEPT
  │   → 执行者修改 → 重新提交 → 审查者 re-review
  │
  └── 有 REJECT/PARTIAL
      → Daemon spawn 审查者看 rebuttal
      ↓
      审查者写入 comments（comment_type="rebuttal_response"）
      ↓
      Daemon 检查：
      ├── 双方达成一致 → 执行者按协商结果修改 → re-review
      ├── 审查者认可执行者反驳 → 执行者修改 → re-review
      └── 仍有分歧
          → round++
          → round < max_rounds → 回到执行者继续协商
          → round >= max_rounds → 升级庞统裁决
```

**唯一的兜底机制**：协商轮次达到 max_rounds 仍未一致 → 升级庞统裁决。庞统裁决也达不成结论 → 升级用户。

**不设超时**——Agent 可能被长任务 block，超时不能等同于"放弃反驳"。轮次上限已经是自然的终止条件。

**进度检测**（催促通知，非阻塞）：如果同一轮次超过 `task_timeout`（10 分钟）没有任何新 comment 写入 → Daemon 通过 Inbox 发一个催促通知给当前应回应的 Agent。不是强制终止，只是提醒。

**reviews 表新增字段**：
- `rebuttal_status`: "pending" | "completed" | "escalated"
- `debate_round`: INTEGER（当前协商轮次，默认 1）

**和 T3-3 对抗辩论的区别**：反驳权是审查后的协商机制（大多数任务），对抗辩论是正式辩论（仅用户明确要求时）。

### 5.4 Agent 调度判据（T3-10 方案）

**调研来源**：Phil Schmid 四种子 Agent 模式、Addy Osmani Code Agent Orchestra、oh-my-opencode 三层调度。

**现有设计已完整**（D3-10 五问题判据 + 场景映射 + 简化规则），补充的是 **Daemon 自动调度逻辑**。

**三级决策树（配置表驱动，非 AI 判断）**：

```python
DISPATCH_RULES = {
    "L1_guardrail":        "daemon",     # Daemon eval guardrails.yaml assert
    "L2_ai_check":         "subagent",   # sessions_spawn 单一检查
    "scope_guard":         "subagent",   # 轻量异步检查
    "execute":             "full_agent", # 走 registered agent
    "review":              "full_agent", # 走 registered agent
    "rebuttal":            "full_agent", # 走原执行者
    "debate_proponent":    "full_agent", # 走原执行者
    "debate_opponent":     "full_agent", # 走挑战者
    "debate_judge":        "full_agent", # 庞统隔离 session
    "plan_decomposition":  "full_agent", # 庞统
}

def dispatch(task, action_type, project_config):
    # 从项目配置动态读取可用 Agent 列表，不硬编码
    registered_agents = project_config.get("agents", [])

    # Level 1: 纯机械检查 → Daemon 直接执行
    if action_type in ("L1_guardrail", "format_check", "file_exists_check"):
        return execute_locally(task)

    # Level 2: 有名字的角色 → Full Agent
    if task.assignee in registered_agents:
        if action_type == "adjudication":
            return spawn_full_agent(task.assignee, new_session=True)
        return spawn_full_agent(task.assignee)

    # Level 3: 无名字的一次性任务 → Subagent
    if DISPATCH_RULES.get(action_type) == "subagent":
        return spawn_subagent(task_description=action_type)

    # Level 4: 未知 action_type → 庞统裁决
    return spawn_full_agent("pangtong-fujunshi", new_session=True)
```

**简化规则**：黑板上有名字的角色（庞统/司马懿/张飞/关羽/赵云/姜维）走 Full Agent。没有名字的一次性检查走 Subagent。纯机械检查 Daemon 自己做。未知类型交给庞统裁决。

**spawn 方式**（和课题11异步计数器模型一致）：
- **Full Agent**：`subprocess.Popen`（非阻塞）启动 `openclaw agent` CLI，不等返回，下次 tick 检查产出
- **Subagent**：`sessions_spawn`（Gateway 内部 API），等返回

## 6. 和现有设计的对齐检查

| 已有设计 | 课题3 补充 | 一致性 |
|---------|-----------|--------|
| §9.5 分级审查矩阵（课题1） | D3-1 分级流水线（补充每级内部流程） | ✅ 四级风险对应四级流水线 |
| §4.7 Guardrail 吹哨人（课题1） | D3-4 Guardrail 结果入 reviews 表 | ✅ 吹哨后写 observation + 入 reviews |
| §3.7 Schema 校验（课题2） | D3-8 Guardrail YAML 和 Schema 对齐 | ✅ L1 检查用 Schema，YAML 声明规则 |
| §4.2 Tick+Inbox（课题2） | 评审触发也走 inbox 通知 | ✅ 挑战者 review 写完后通知 Daemon |
| §5.1 Handoff Comment（课题2） | §4 评审与 Handoff 关系 | ✅ Handoff 是执行者写的，review 是挑战者写的 |
| §3.2 SQLite Schema | reviews 表新增 | ✅ 独立新表，不修改现有表 |
