auto-sync: 2026-06-06 10:14:07

This commit is contained in:
cfdaily
2026-06-06 10:14:07 +08:00
parent b8204a0806
commit 5f4861aea7
@@ -1064,3 +1064,284 @@ Text:
3. **数据库 schema 变更检查**:CI 自动检测破坏性变更(可选,有开关可强制绕过),检测不到的提 Issue 人工干预 — **已确认**
4. **环境架构**:三环境(开发/CI临时/生产),CI 临时环境支持 E2E 自动跑不污染生产 — **已确认**
5. **Webhook 转发模块集成到 daemon**:已确认方向,具体实现待设计(见 §15)
---
## §15. 串联架构
> §15 是 v2.0 的核心新增章节,定义工具链三层串联架构:Gitea 自动化 + Daemon Webhook 模块 + Mail 执行层。
> 此架构取消了之前的 ci-notifier 虚拟角色概念,所有事件流转通过三层清晰分工完成。
### §15.1 串联架构总览
三层架构图:
```
Layer 1: Gitea 自动化(流程引擎)
- Actions: push → CI, PR → CI, merge → deploy
- Status Check: CI 结果自动显示在 PR
- Branch Protection: CI通过+Review通过才许merge
- CI workflow 内可调 Gitea API 写 PR 评论
Layer 2: Daemon 流程编排(转发+监控)
- Webhook 接收模块:监听 /webhook 端点
- 简单事件:Webhook → 解析 → 直接发 Mail
- 复杂事件:Webhook → 解析 → spawn 庞统作为任务节点
- 超时检测:在 ticker 中扫描未回复 Mail
- 失败处置:轻度重发提醒,中度 spawn 庞统,严重创建 Issue
Layer 3: Mail 执行层(Agent 接口)
- Mail = 流程指令 + 回复确认 + 时限
- Agent 收到 Mail 后行动,完成后回复确认
- Mail 线程 = Issue 生命周期可追溯
- 流程强约束固化在 Mail 模板中
```
核心原则:
1. **Gitea 是流程引擎**——所有状态流转靠 Gitea 自己(Actions + Status Check + Branch Protection
2. **Webhook → Mail 转发集成在 daemon 里**——状态共享,可直接触发下一步
3. **Mail 是 Agent 接口**——Agent 不看 Gitea UI,所有需 Agent 行动的事件通过 Mail 推送
4. **简单事件 daemon 直接处理,复杂事件(多 Agent 协作)spawn 庞统作为协调节点**
5. **没有 ci-notifier**——不需要虚拟角色,Gitea 是流程引擎,daemon 是翻译器+监控器
### §15.2 Gitea Webhook 能力清单
| 事件类型 | 触发时机 | Payload 关键字段 | 工具链用途 |
|---------|---------|----------------|-----------|
| `push` | 代码推送 | commit hash, 分支, 作者 | 不需要转发(Actions 自动处理) |
| `pull_request` (opened) | PR 创建 | PR ID, 标题, 分支, 作者 | → Mail 通知司马懿 Review |
| `pull_request_review` (submitted) | Review 提交 | PR ID, 审查者, 结论(APPROVE/REQUEST_CHANGES), 评论 | → Mail 通知张飞 Review 结果 |
| `pull_request` (closed/merged) | PR 合并 | PR ID, 合并 commit | 不需要转发(Actions 自动触发 deploy |
| `issue_comment` | PR/Issue 评论 | 评论者, 内容 | CI workflow 写的失败评论 → 转发 Mail |
| `issues` (opened+assigned) | Issue 创建/指派 | Issue ID, 标题, 被指派人 | → Mail 通知开发者 |
| `release` | Release 创建 | tag, 名称 | 触发完整 CI+部署 |
> **说明**Webhook 是单向 POSTGitea 发完不管。需要在 daemon 里实现 `/webhook` 端点接收。
### §15.3 Daemon Webhook 模块设计
在 daemon 中新增一个 Webhook 接收模块(FastAPI 路由):
```python
# src/api/webhook_routes.py
@router.post("/webhook/gitea")
async def handle_gitea_webhook(event: dict, x_gitea_event: str = Header(...)):
"""接收 Gitea Webhook,翻译成 Mail 或 spawn 庞统"""
if x_gitea_event == "pull_request":
action = event["action"]
if action == "opened":
# 简单事件:直接发 Mail 通知司马懿
await send_mail(to="simayi-challenger", title=f"Review 请求: PR #{event['number']}", ...)
elif action == "closed" and event["pull_request"]["merged"]:
# merge 不需要通知,Actions 自动处理
pass
elif x_gitea_event == "pull_request_review":
state = event["review"]["state"]
if state == "APPROVED":
await send_mail(to=event["pull_request"]["user"]["login"],
title=f"Review 通过: PR #{event['number']},请 merge", ...)
elif state == "REQUEST_CHANGES":
await send_mail(to=event["pull_request"]["user"]["login"],
title=f"Review 不通过: PR #{event['number']}", ...)
elif x_gitea_event == "issue_comment":
# CI 自动写的失败评论 → 转发给相关 Agent
if "CI 失败" in event["comment"]["body"]:
await send_mail(to=event["sender"]["login"],
title=f"CI 失败: PR #{event['number']}", ...)
elif x_gitea_event == "issues":
if event["action"] == "assigned":
assignee = event["assignee"]["login"]
await send_mail(to=assignee,
title=f"任务指派: Issue #{event['number']}", ...)
```
关键设计:
- 模块部署在 daemon 的 FastAPI 里(已有服务,只加路由)
- 和 Mail API 共享 SQLite(直接调内部函数,不经过 HTTP)
- 简单事件(CI失败通知、Review通知、任务指派)直接发 Mail
- 复杂事件(部署失败、架构级 Review 问题)spawn 庞统
### §15.4 超时检测与失败处置
**检测机制**daemon ticker 中新增一个定时扫描任务(每小时跑一次)
```python
# 在 daemon ticker 中
async def check_stale_flows():
"""扫描超时未回复的 Mail"""
# 1. 查所有 type=request 且无 in_reply_to 回复的 Mail
stale_mails = queries.find_stale_requests(deadline_hours=4)
for mail in stale_mails:
hours_overdue = (now() - mail.created_at).total_seconds() / 3600
if hours_overdue < 8:
# 轻度:重发 Mail 提醒
await send_mail(to=mail.to, title=f"提醒: {mail.title}",
text=f"此任务已超时 {hours_overdue:.0f} 小时,请尽快处理。")
elif hours_overdue < 24:
# 中度:spawn 庞统介入
await spawn_agent("pangtong-fujunshi",
f"流程卡住: Mail {mail.id} '{mail.title}' 超时 {hours_overdue:.0f} 小时未回复。请介入协调。")
else:
# 严重:创建 Issue + 通知主公
await create_issue(title=f"流程严重超时: {mail.title}", labels=["blocked", "priority:high"])
await send_mail(to="pangtong-fujunshi",
title=f"严重超时: {mail.title},已创建 Issue", ...)
```
**失败处置原则**
- 所有失败 → Issue 走正式流程,不私下通知 Agent 悄悄解决
- CI 失败 → CI workflow 写 PR 评论 → Webhook → Mail 通知 → Agent 修 → 走标准 PR 流程
- 部署失败回滚 → CI workflow 创建 Issuepriority:high → 走标准 Bug 修复流程
- 超时未响应 → 三级处置(提醒→庞统介入→Issue+通知主公)
**断点续传**
- 每个环节的状态都在 Gitea 上(PR 状态、CI 结果、Review 状态)
- Mail 线程提供完整的可追溯记录
- 流程卡住时,庞统可以根据 Mail 线程 + Gitea 状态快速定位断点并继续
### §15.5 Mail 模板(流程强约束固化)
> **注意**:Mail 模板里固化的是**流程强约束**——这个工作链特有的一步步怎么做。
> 共通技能(git 操作、审查清单等)放在 Skill 里(见 §10)。
**模板 1:任务指派(庞统/daemon → 开发者)**
```
Title: 任务指派: Issue #{N} - {标题}
Text:
Issue: {url}
分支: {branch_name}
风险级别: {level}
验收标准: {criteria}
流程:
1. 创建分支 {branch_name}
2. 编码 + 写 UT
3. push → 等 CICI 会自动跑)
4. CI 通过后创建 PRGitea API: POST /repos/{owner}/{repo}/pulls
5. 等 Review(司马懿会自动收到通知)
6. Review 通过后 merge PR
如果 CI 失败:修复后重新 push,回到步骤 3
如果 Review 不通过:按意见修改后重新 push,回到步骤 3
完成后回复此 Mail 确认。
时限:{deadline}
```
**模板 2Review 请求(Webhook → 司马懿)**
```
Title: Review 请求: PR #{N}
Text:
PR: {url}
标题: {title}
风险级别: {level}
改动文件: {file_list}
流程:
1. 读取 PR diffGitea API: GET /repos/{owner}/{repo}/pulls/{N}.diff
2. 按审查清单审查(参考 code-review Skill
3. 提交 ReviewGitea API: POST /repos/{owner}/{repo}/pulls/{N}/reviews
- APPROVE 或 REQUEST_CHANGES
4. 提交后张飞会自动收到通知
完成后回复此 Mail 确认。
时限:{deadline}
```
**模板 3Review 结果通知(Webhook → 张飞)**
```
Title: Review {result}: PR #{N}
Text:
PR: {url}
结果: {APPROVED / REQUEST_CHANGES}
审查意见: {review_body}
{如果通过}:
流程:merge PRGitea API: POST /repos/{owner}/{repo}/pulls/{N}/merge
{如果不通过}:
流程:
1. 按审查意见修改代码
2. push → CI 自动跑
3. CI 通过后等重新 Review
完成后回复此 Mail 确认。
```
**模板 4CI 失败通知(Webhook from issue_comment → 张飞)**
```
Title: CI 失败: PR #{N}
Text:
PR: {url}
失败测试: {failed_tests}
错误摘要: {error_summary}
流程:
1. 查看完整 CI 日志(PR 页面)
2. 修复失败的测试
3. push → CI 自动重跑
完成后回复此 Mail 确认。
```
**模板 5:部署失败通知(→ 庞统,复杂事件 spawn)**
```
Title: 部署失败已回滚: {repo}
Text:
仓库: {repo}
触发 commit: {sha}
失败原因: {error}
已自动回滚到: {previous_version}
已自动创建 Issue #{M}。
请协调排查。
```
### §15.6 Skill vs Mail 边界
| 维度 | Mail 模板 | Skill |
|------|----------|-------|
| 作用域 | 工具链流程特有 | 全局,所有项目通用 |
| 强制度 | 强约束,Agent 必须按流程走 | 按需加载,提升质量 |
| 内容 | 流程步骤+Gitea API 调用指令 | 共通技能(审查清单、git规范等) |
| 示例 | "CI失败→修→push→等CI→等Review" | "怎么写好 UT"、"审查清单" |
| 没有 Skill 能否运转 | ✅ 能(流程不会断) | 只是质量没那么高 |
**原则:没有 Skill,流程还能运转。有了 Skill,流程运转得更好。**
Skill 只放共通的、所有项目都能用的技能:
- `git-workflow`:分支命名、commit 规范(所有项目通用)
- `code-review`:审查清单(所有项目通用)
- `testing-workflow`:测试规范(所有项目通用)
- `bugfix-workflow`:根因定位方法(所有项目通用)
工具链特有的流程("CI 失败后怎么做"、"Review 通过后怎么做")全部固化在 Mail 模板里。
### §15.7 Agent ID ↔ Git 用户名映射
CI workflow 和 Webhook 中的用户标识是 Git 用户名,Mail API 需要 Agent ID
| Git 用户名 | Agent ID |
|-----------|----------|
| zhangfei | zhangfei-dev |
| jiangwei | jiangwei-infra |
| simayi | simayi-challenger |
| pangtong | pangtong-fujunshi |
| guanyu | guanyu-dev |
| zhaoyun | zhaoyun-data |
daemon Webhook 模块中维护此映射表。