# §21. Handler 注册后 E2E 验证

> 日期：2026-06-11
> 状态：已完成 ✅
> 目标：验证 Task 五层架构重构（Step 2-5）+ review 修复后，Mail/Toolchain 路径端到端工作

## 前置条件

- Daemon 版本：commit 83694ad（含 handler 注册 + import 修复 + SKILL_BASE_PATH 修复）
- Handler 注册日志：
  ```
  Registered task type handler: task (virtual_project=None)
  Registered task type handler: mail (virtual_project=_mail)
  Registered task type handler: toolchain (virtual_project=_toolchain)
  ```
- Gitea org webhook (ID=28)：姜维启用，事件订阅含 issues/pull_request/pull_request_review 等 16 个事件
- 测试仓库：sanguo/sanguo_moziplus_v2

## 验证结果

### 一、Mail Handler（✅ 全部通过）

| # | 步骤 | 验证点 | 结果 | Mail ID |
|---|------|--------|------|---------|
| 1 | 发 inform 邮件给 zhangfei-dev | ticker 发现 `_mail` 虚拟项目 | ✅ `handler auto-working` | mail-1781106713261 |
| 2 | zhangfei-dev 回复 | handler verify (inform_auto) → done | ✅ `verify passed (inform_auto), marked done` | — |
| 3 | 回复邮件给 pangtong | handler auto-working + done | ✅ `verify passed (inform_auto), marked done` | mail-1781106736388 |

**关键验证**：
- ✅ `virtual_projects()` 返回 `["_mail", "_toolchain"]`（注册前为空）
- ✅ handler `pre_spawn` (auto-working) 生效，不是旧的 `_mail_auto_working`
- ✅ guardrail 跳过 `_mail`（`is_handler_task=True`）
- ✅ inform 类型自动标 done，request 类型检查回复

### 二、Toolchain — Issue 指派（✅ 通过）

| # | 步骤 | 验证点 | 结果 | Mail ID |
|---|------|--------|------|---------|
| 1 | 创建 Issue #28，assignee=zhangfei-dev | webhook 触发 + Mail 通知 | ✅ | mail-1781107087549 |

**Webhook 路径**：Gitea → org webhook → `POST /webhook/gitea` → 签名验证 → `_handle_issues` → `_send_mail(zhangfei-dev, ...)`

**注意**：Issue #27 创建时 webhook 未启用，未触发。Issue #28 创建时 webhook 已启用，正常触发。

### 三、Toolchain — PR Review（✅ 通过）

| # | 步骤 | 验证点 | 结果 | Mail ID |
|---|------|--------|------|---------|
| 1 | 创建 PR #30 | webhook 触发 + Review 请求 Mail | ✅ | mail-1781107538823 |
| 2 | simayi-challenger 提交 COMMENT review | Review 结果通知 PR 作者 | ✅ `Review 通过 ✓` | mail-1781107650433 |

**Webhook 路径**：
- PR opened: Gitea → `_handle_pull_request` → `_send_mail(simayi-challenger, "Review 请求")`
- PR review: Gitea → `_handle_pull_request_review` → `_send_mail(pangtong-fujunshi, "Review 通过 ✓")`

### 四、CI 失败评论（⚠️ 触发但重复）

| # | 步骤 | 验证点 | 结果 | Mail ID |
|---|------|--------|------|---------|
| 1 | push 空 commit → CI lint 失败 | CI 失败通知 | ✅ 但收到 2 封重复 Mail | mail-1781107563991, mail-1781107560933 |

**已知问题**：和上次 E2E（§18）相同——org webhook + repo webhook 双触发。上次已加去重机制（delivery UUID + content sha256），但 CI 失败场景似乎仍触发 2 封。**非新问题，待姜维统一 org/repo webhook 后解决。**

### 五、负面测试（❌ 未执行）

| 步骤 | 说明 | 状态 |
|------|------|------|
| REQUEST_CHANGES review | review 驳回通知 PR 作者 | 未测（仲达提交的是 COMMENT 而非 REQUEST_CHANGES） |
| 已关闭 Issue CI 评论 | closed issue 不触发 Mail | 未测 |
| 部署失败 Issue | 双收件人通知 | 未测 |
| 幂等测试 | 同 delivery ID 重发 | §18 已验证，未重测 |

## 阻塞/问题记录

### 已解决

| 问题 | 说明 |
|------|------|
| Org webhook 事件列表被 Gitea API 重置 | 姜维修复：PATCH webhook 只传 active:true 会重置 events，必须带完整事件列表 |
| PR Review 无法用 PR 作者 token 提交 | Gitea 不允许 self-review，请仲达用 simayi token 提交 |

### 遗留

| 问题 | 严重度 | 说明 |
|------|--------|------|
| CI 失败 Mail 重复 | 🟡 | org webhook + repo webhook 双触发，§18 已记录 |
| REQUEST_CHANGES 未验证 | 🟢 | 下次 E2E 补测 |

## 测试清理

- ✅ Issue #27、#28 已关闭
- ✅ PR #29、#30 已关闭
- ✅ 分支 `test/e2e-1781107119`、`test/e2e-pr-1781107530` 已删除
- ✅ 本地切回 main 分支

## 结论

**Handler 注册后 Mail 和 Toolchain 核心流程端到端验证通过。** 关键修复（handler 注册、review verdict、SKILL_BASE_PATH）均已生效。

下一步：
- Task review 路径 E2E（明天，需要普通任务 → executor → review → verdict → done）
- CI 失败重复 Mail 根治（需姜维统一 org/repo webhook）
