From 5f4861aea7b78248b1b8e97f5c6cd1e32fc7e50f Mon Sep 17 00:00:00 2001 From: cfdaily Date: Sat, 6 Jun 2026 10:14:07 +0800 Subject: [PATCH] auto-sync: 2026-06-06 10:14:07 --- docs/design/13-toolchain-and-dev-workflow.md | 281 +++++++++++++++++++ 1 file changed, 281 insertions(+) diff --git a/docs/design/13-toolchain-and-dev-workflow.md b/docs/design/13-toolchain-and-dev-workflow.md index d09792d..360786b 100644 --- a/docs/design/13-toolchain-and-dev-workflow.md +++ b/docs/design/13-toolchain-and-dev-workflow.md @@ -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 是单向 POST,Gitea 发完不管。需要在 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 创建 Issue(priority: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 → 等 CI(CI 会自动跑) + 4. CI 通过后创建 PR(Gitea API: POST /repos/{owner}/{repo}/pulls) + 5. 等 Review(司马懿会自动收到通知) + 6. Review 通过后 merge PR + + 如果 CI 失败:修复后重新 push,回到步骤 3 + 如果 Review 不通过:按意见修改后重新 push,回到步骤 3 + + 完成后回复此 Mail 确认。 + 时限:{deadline} +``` + +**模板 2:Review 请求(Webhook → 司马懿)** + +``` +Title: Review 请求: PR #{N} +Text: + PR: {url} + 标题: {title} + 风险级别: {level} + 改动文件: {file_list} + + 流程: + 1. 读取 PR diff(Gitea API: GET /repos/{owner}/{repo}/pulls/{N}.diff) + 2. 按审查清单审查(参考 code-review Skill) + 3. 提交 Review(Gitea API: POST /repos/{owner}/{repo}/pulls/{N}/reviews) + - APPROVE 或 REQUEST_CHANGES + 4. 提交后张飞会自动收到通知 + + 完成后回复此 Mail 确认。 + 时限:{deadline} +``` + +**模板 3:Review 结果通知(Webhook → 张飞)** + +``` +Title: Review {result}: PR #{N} +Text: + PR: {url} + 结果: {APPROVED / REQUEST_CHANGES} + 审查意见: {review_body} + + {如果通过}: + 流程:merge PR(Gitea API: POST /repos/{owner}/{repo}/pulls/{N}/merge) + + {如果不通过}: + 流程: + 1. 按审查意见修改代码 + 2. push → CI 自动跑 + 3. CI 通过后等重新 Review + + 完成后回复此 Mail 确认。 +``` + +**模板 4:CI 失败通知(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 模块中维护此映射表。