49 KiB
三国团队工具链与开发流程设计
状态: v1.1 — 补充全局工作流串联图 作者: 庞统(副军师)🐦 评审: 司马懿(仲达)🗡️ 日期: 2026-06-06 v0.4 变更: 主公 6 条反馈(需求review前置、E2E用户触发、测试分工、审查默认司马懿、项目维度组织、分支保护说明) v0.5 变更: E2E 改为自动跑(CI隔离环境不污染生产)、三环境架构、schema变更检查确认、分支保护确认开启 v0.6 变更: Agent spawn 走生产 openclaw(不隔离)、程序逻辑走 CI 隔离环境、路径硬编码修复清单 定位: 普适工具链和开发流程,适用于三国团队所有项目,与 moziplus 2.0 解耦
§1. 设计原则
| # | 原则 | 说明 |
|---|---|---|
| 1 | 声明式 + 代码执行分离 | 规则声明在配置中,执行由框架代码保证,不依赖 Agent 自觉(来源: moziplus-quality-governance) |
| 2 | 能自动就自动 | CI/CD/部署能自动触发就不手动,人只做决策和审查 |
| 3 | Skill 固化流程 | 所有流程通过 Skill(提示词)固化,不靠口头约定 |
| 4 | 分级治理 | 按风险级别选择流程严格度,不搞一刀切(来源: quality-gate-patterns) |
| 5 | 验证才算完 | Agent 说"完成"不算,CI 通过 + 产出物存在才算(来源: 幻觉门控) |
| 6 | 每个项目自带部署 | 部署脚本归项目管,工具链负责触发和验证,不替项目做部署决策 |
| 7 | 需求/问题必须经过 Review | 所有需求和问题提交前必须经过 Review,不直接进入开发 |
| 8 | 项目维度组织 | 所有内容(Issue、CI、部署、Skill 配置)以项目为单位组织,支持多项目并行 |
§2. 基础设施层
2.1 代码托管:Gitea(唯一)
| 项 | 配置 |
|---|---|
| 地址 | http://192.168.2.154:3000 |
| 版本 | v1.23.4 |
| 认证 | HTTP + token(待配置) |
| 权限 | cfdaily 用户;姜维持有 admin 权限(启用 Actions、分支保护等) |
2.2 CI/CD:Gitea Actions
| 项 | 配置 |
|---|---|
| Runner | Mac mini 裸机,act-runner(Go 二进制) |
| 配置文件 | .gitea/workflows/*.yml,每个项目自管 |
| 语法 | 兼容 GitHub Actions(v1.23.4 已验证支持) |
| 触发 | push / PR / tag |
2.3 部署目标
| 环境 | 位置 | 说明 |
|---|---|---|
| Mac mini 本机 | ~/.sanguo_projects/<project>/ |
主力开发和运行环境 |
| NAS Docker | 192.168.2.154 |
部分服务(Gitea、回测等) |
§3. 分支策略
3.1 采用 Trunk-Based Development(简化版)
选 Trunk-Based 而非 Git Flow 的理由:
- 团队小(<10 人),不需要复杂的 release 分支
- AI Agent 参与编码,Agent 在短生命周期 feature 分支上工作,完成后快速合并
- CI 是安全网,main 分支始终可部署,feature 分支通过 CI 才能合并
前提条件:Agent 必须知道当前所在分支。git-workflow Skill 需注入 git branch --show-current 到 Agent 上下文(仲达 Q1 补充)。
3.2 分支规则
| 分支类型 | 命名 | 生命周期 | 合并方式 | 适用场景 |
|---|---|---|---|---|
main |
main |
永久 | — | 始终可部署 |
| feature | feat/<issue-N>-<简述> |
<3天 | PR → CI → Review → merge | 新功能 |
| bugfix | fix/<issue-N>-<简述> |
<1天 | PR → CI → merge | Bug 修复 |
| hotfix | hotfix/<简述> |
<2小时 | 直接 push main + CI + 自动回滚 | 紧急修复 |
3.3 分支保护规则
main分支:- 不允许直接 push(hotfix 除外)
- PR 必须通过 CI(至少 unit + integration tests)
- PR 必须至少 1 人 Review(人或 Agent)
- hotfix 直接 push main 后必须触发 CI(至少 lint + unit),CI 失败则自动 revert(M1 修订)
- feature/bugfix 分支:
- 无保护,自由 push
- 合并前必须 CI 通过
3.4 Commit 规范
<type>(<scope>): <subject>
<body>
| type | 说明 |
|---|---|
feat |
新功能 |
fix |
Bug 修复 |
refactor |
重构(不改行为) |
test |
测试相关 |
docs |
文档 |
chore |
构建/工具/配置 |
§4. 问题管理
4.1 问题来源
| 来源 | 入口 | 处理方式 |
|---|---|---|
| 主公口头 | 庞统记录,经 Review 后 | 创建 Gitea Issue |
| 司马懿 Review | Review 意见 | 创建 Gitea Issue,关联 PR |
| 自动化测试失败 | CI 报告 | 自动评论到已有 Issue,或手动创建 |
| 用户测试反馈 | 人工报告 | 创建 Gitea Issue |
| Agent 运行发现 | Agent 日志,经 Review 后 | 创建 Gitea Issue |
4.2 Issue 标签体系
| 标签 | 颜色 | 说明 |
|---|---|---|
bug |
红 | 功能异常 |
feature |
蓝 | 新功能需求 |
improvement |
绿 | 改进优化 |
security |
橙 | 安全相关 |
risk:high/standard/low |
分级色 | 风险级别(见 §6.1 判定规则) |
priority:high/medium/low |
黄/灰 | 优先级 |
blocked |
紫 | 阻塞中 |
4.3 需求/问题 Review 前置
所有需求和问题在进入开发之前必须经过 Review:
| 类型 | Review 者 | 目的 |
|---|---|---|
| 新需求 | 庞统(方案合理性)+ 司马懿(技术可行性) | 确认需求清晰、可行、值得做 |
| Bug/问题 | 司马懿(确认根因)或庞统(确认优先级) | 确认是真 bug、不是误报,根因明确 |
| Agent 发现的问题 | 庞统(确认有效性) | 过滤误报 |
未经过 Review 的 Issue 不进入开发流程。
4.4 Issue 状态流转
Open → In Progress → Review → Closed
↑ ↓
└──── Reopened ←───────────────────┘
§5. CI/CD 管道设计
5.1 通用 CI 流程(所有项目共享骨架)
每个项目在 .gitea/workflows/ci.yml 自定义具体步骤,但遵循统一骨架。
注:Gitea Actions v1.23.4 不支持
paths过滤触发条件。通过路径判断放在 job 级别的if条件中,使用确定支持的语法。(M4 修订)
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# Job 1: 后端测试
backend:
# 只在有 Python 代码变更时跑
runs-on: [self-hosted, mac-mini]
steps:
- uses: actions/checkout@v4
- name: Setup Python
run: |
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
- name: Lint
run: .venv/bin/ruff check src/
- name: Unit Tests
run: .venv/bin/pytest tests/unit/ -m "not e2e" --tb=short
- name: Integration Tests
run: .venv/bin/pytest tests/integration/ --tb=short
- name: Coverage Report
run: .venv/bin/pytest --cov=src --cov-report=term-missing
# Job 2: 前端构建
frontend:
# 只在有前端目录时跑
runs-on: [self-hosted, mac-mini]
steps:
- uses: actions/checkout@v4
- name: Install & Build
run: |
cd src/frontend
npm ci
npm run build
- name: Type Check
run: cd src/frontend && npx tsc --noEmit
实际使用时:每个项目根据实际情况删减 job。没有前端的删 frontend job,没有 Python 的删 backend job。
5.2 CI 门控级别
| 级别 | 触发条件 | 跑什么 | 阻断行为 |
|---|---|---|---|
| 快速 | feature 分支 push | lint + unit tests | 软阻断:失败标红,创建 PR 时如果最近一次 CI 失败则不允许进入 Review(S2 修订) |
| 标准 | PR 到 main | lint + unit + integration + coverage | 阻断 merge |
| 完整 | tag / main push | 标准 + build(E2E 仅 tag 触发) | 阻断部署 |
| 手动 | 手动触发 | 完整 + 特定检查 | 按需 |
5.3 覆盖率渐进策略(仲达 Q3 补充)
当前多数项目从未跑过覆盖率,直接设阈值不现实。分三阶段:
| 阶段 | 时间 | 覆盖率策略 | 说明 |
|---|---|---|---|
| P1 | 启用后 2 周 | 只报告不阻断 | 先拿基线数据 |
| P2 | 启用后 1 月 | 40% 阈值,低于警告不阻断 | 逐步提升 |
| P3 | 启用后 2 月+ | 60% 阈值,低于阻断 | 正式生效 |
5.4 CI 结果反馈
- ✅ 通过 → PR 可合并
- ❌ 失败 → PR 阻断,自动评论失败信息
- 覆盖率低于阈值 → P1 只报告,P2 警告,P3 阻断
§6. 代码审查流程
6.1 风险级别判定规则(M2 修订)
风险级别不由改动者自评,按以下规则自动判定 + 非改动者确认:
自动判定规则(在 CI 或 PR 模板中检查):
| 规则 | 级别 | 触发条件 |
|---|---|---|
| 涉及核心模块 | 高 | 改动文件匹配 **/spawner*、**/ticker*、**/dispatcher*、**/router*、**/guardrails*、**/strategy*、**/risk* |
| 涉及资金/安全 | 高 | 改动包含交易逻辑、风控规则、密钥管理、资金操作 |
| 数据库 schema 变更 | 高 | 改动匹配 **/migrations/**、**/schema*、**/models.py 中的表定义 |
| 常规功能开发 | 标准 | 不匹配高风险规则的 src/ 下改动 |
| 文档/测试/配置 | 低 | 改动仅在 docs/、tests/、*.md、*.yaml(非 guardrails) |
确认机制:
- PR 创建时自动标注风险级别(基于 git diff 文件路径)
- 审查者(或庞统)确认或升级——只能升级不能降级
- 改动者可以申请升级(但不能申请降级)
6.2 审查方式(按风险分级)
| 风险级别 | 审查方式 | 审查者 |
|---|---|---|
| 高 | 固定 Review(必须) | 司马懿(专职) |
| 标准 | 固定 Review(必须) | 司马懿(默认审查者) |
| 低 | 简化走查 | 司马懿(快速确认)+ CI 通过 |
例外:司马懿自己的改动 → 庞统交叉审查。
所有级别的代码审查默认由司马懿执行。只有司马懿作为改动者时,才由庞统进行交叉审查。不再按改动领域分配审查者——简化流程,减少协调成本。
6.3 审查者分配规则
| 改动者 | 审查者 |
|---|---|
| 张飞 / 姜维 / 关羽 / 赵云 / 庞统 | 司马懿(默认) |
| 司马懿 | 庞统(交叉审查) |
6.4 审查清单(Skill 固化)
审查清单通过 Skill 提示词固化,不依赖审查者自觉。基础清单 + 项目类型变体:
基础清单(所有项目通用):
1. 正确性
- [ ] 代码逻辑正确,无死循环/空指针/边界遗漏
- [ ] 异常处理完整(网络超时、文件不存在、参数非法)
- [ ] 改动范围和 Issue/需求描述一致(不多不少)
2. 一致性
- [ ] 命名规范统一(变量/函数/文件)
- [ ] 和已有代码风格一致
3. 安全性
- [ ] 无硬编码密钥/密码/Token
- [ ] 用户输入有校验
- [ ] 文件操作有路径校验
4. 可维护性
- [ ] 复杂逻辑有注释(为什么,不是做什么)
- [ ] 无重复代码(DRY)
- [ ] 关键参数可配置,无魔法数字
5. 测试覆盖
- [ ] 新功能有对应测试
- [ ] Bug 修复有回归测试
- [ ] CI 通过
结论:通过 / 不通过(附具体行号和修改方向)
量化策略项目变体(追加项):
6. 量化策略专项
- [ ] 止损逻辑完整(触发条件、执行路径、异常兜底)
- [ ] 仓位计算正确(滑点、手续费已计入)
- [ ] 回测参数和实盘参数分离
6.5 审查时效
| 改动大小 | 期望审查时间 |
|---|---|
| < 100 行 | 2 小时内 |
| 100-500 行 | 半天内 |
| > 500 行 | 1 天内 |
§7. 部署流程
7.1 部署触发
| 触发方式 | 适用场景 | 流程 |
|---|---|---|
| 自动(tag 触发) | 正式发布 | 打 tag → CI 完整跑(含 E2E)→ 自动执行 deploy 脚本 → 健康检查 |
| 自动(main push) | 日常迭代 | push main → CI 标准跑 → 自动执行 deploy 脚本 → 健康检查 |
| 手动 | 紧急/调试 | 手动执行项目 deploy 脚本 |
7.2 项目部署脚本规范
每个项目必须提供 scripts/deploy.sh,接口统一:
#!/usr/bin/env bash
# deploy.sh — 项目部署脚本
#
# 必须支持的参数:
# --source=DIR 源码目录(CI 自动传入:源码 checkout 路径)
# --target=DIR 安装目标目录(CI 自动传入:安装路径)
# --skip-build 跳过构建步骤
# --health-check 部署后执行健康检查
# --version 输出当前部署版本(tag + commit hash + 部署时间)
# --rollback 回滚到上一个已记录的部署版本
#
# 必须维护的文件:
# data/deploy-history.jsonl — 最近 10 个部署版本记录
# 每行: {"tag":"v1.2.3","commit":"abc123","timestamp":"2026-06-06T12:00:00+08:00","status":"success"}
#
# 必须返回:
# 0 = 成功
# 非0 = 失败(stderr 输出原因)
7.3 自动部署 Workflow
# .gitea/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
tags: ['v*']
jobs:
deploy:
needs: [ci] # 依赖 CI 通过
runs-on: [self-hosted, mac-mini]
steps:
- uses: actions/checkout@v4
- name: Record current version
run: bash scripts/deploy.sh --version
- name: Deploy
run: bash scripts/deploy.sh --source="$GITHUB_WORKSPACE" --health-check
- name: Rollback on failure
if: failure()
run: bash scripts/deploy.sh --rollback
7.4 健康检查
每个项目的 deploy 脚本必须包含健康检查:
- HTTP 服务:
curl -sf http://localhost:<port>/api/health - 数据服务:数据连通性检查
- 定时任务:PM2 状态检查
7.5 回滚策略(M3 修订)
版本记录:
- 每次 deploy 成功后,记录 tag + commit + 时间戳到
data/deploy-history.jsonl(保留最近 10 条) --version读取最后一行输出当前版本--rollback读取倒数第二行,checkout 对应 commit,重新 deploy
回滚流程:
deploy.sh --rollback读取上一个成功版本git checkout <previous-commit>- 重新执行 deploy(不含 rollback)
- 健康检查
已知限制:
- revert 可能产生合并冲突 → 部署失败时人工介入
- 数据库变更回滚需人工介入 → schema 变更必须向前兼容(只加字段不删/不改),违反此规范由 CI 检查拦截(或人工 Review 拦截)
§8. 验证流程集成
8.1 验证来源和层级
| 验证来源 | 层级 | 触发时机 | 自动化程度 |
|---|---|---|---|
| Lint | 机械 | 每次 push | 100% 自动 |
| 单元测试 | 机械 | 每次 push | 100% 自动 |
| 集成测试 | 语义 | PR 到 main | 100% 自动 |
| 覆盖率 | 语义 | PR 到 main | 渐进自动(见 §5.3) |
| Code Review | 共识 | PR 到 main | 人工(Skill 辅助) |
| E2E 测试 | 共识 | PR 到 main 时自动跑(CI 隔离环境)+ 手动触发 | 自动+手动 |
| 用户测试 | 共识 | 部署后 | 手动 |
8.2 三阶段门控(来源: quality-gate-patterns)
机械门控 (CI 快速) → 语义门控 (CI 标准 + Review) → 共识门控 (E2E + 用户验证)
零成本 中等成本 高成本
语法/lint/编译 API 契约/业务逻辑 端到端/用户体验
- 快速门控是开发期辅助反馈,不替代标准门控
- PR 合入必须经过标准门控(机械 + 语义),这个顺序不可跳过(S3 修订)
- 机械失败 → 立即阻断,不看 Review
- 语义失败 → 可以 Review 但不能合并
- E2E 在 CI 隔离环境中自动跑,不污染生产环境(见 §8.5)。也可手动触发。
8.3 测试失败 → Issue 关联
- CI 失败时,如果已有 Issue → 自动评论失败信息
- CI 失败时,如果无 Issue → 不自动创建(避免 Issue 爆炸),由改动者手动创建
8.4 机械门控前提条件(仲达 Q6 补充)
P1 必须先配好以下工具,否则机械门控跑不起来:
| 工具 | 用途 | 安装 |
|---|---|---|
ruff |
Python lint + format | pip install ruff |
pytest-cov |
覆盖率 | pip install pytest-cov |
act-runner |
CI 执行器 | 下载 Go 二进制 |
8.5 CI 隔离测试环境(E2E 安全运行)
E2E 自动跑的核心前提:不污染生产环境。通过 CI 隔离环境实现:
CI 临时测试环境(每次 CI 自动创建)
├─ 独立 venv(每次 CI 新建)
├─ 临时 SQLite(tmpdir,跑完销毁)
├─ 临时端口(8084,不和生产 8083 冲突)
├─ 启动 FastAPI 服务 → 跑 E2E → 关闭
└─ 跑完整个 tmpdir 删除,不留痕迹
生产环境(~/.sanguo_projects/)完全不受影响
效果:E2E 可以在每次 PR 到 main 时自动跑,无需担心污染生产数据或影响生产服务。
隔离边界:程序逻辑 vs Agent 交互
| 层面 | 隔离方式 | 说明 |
|---|---|---|
| 程序逻辑(FastAPI + Daemon + SQLite) | ✅ 完全隔离 | 独立 venv + 临时数据库 + 临时端口 |
| Agent spawn(openclaw agent) | ❌ 走生产 openclaw | openclaw 是全局单例,无法隔离 |
Agent spawn 走生产 openclaw 的决策理由:
- openclaw 是全局单例(
~/.openclaw/只有一份),Agent 配置和 workspace 全局共享 - 测试 case 会标识测试上下文,Agent 记忆混淆风险低
- 完全隔离需要在 Docker 中跑独立 openclaw,维护成本不值得
- Agent 的 API 回写地址由 spawn message 传入,指向 CI 临时服务的端口 8084
路径硬编码修复清单
当前代码有 6 处硬编码绝对路径,需改为环境变量可配置(P1 必须完成):
| 位置 | 硬编码路径 | 改法 | 现状 | 行数 |
|---|---|---|---|---|
utils.py |
数据根目录 | BLACKBOARD_ROOT 环境变量 |
✅ 已支持 | 1 |
bootstrap.py:42 |
Skill 加载路径 | MOZI_SKILL_PATH 环境变量 |
✅ 已支持 | 1 |
registry.py:264 |
项目扫描目录 ~/.openclaw/sanguo_projects |
加 SANGUO_PROJECTS_DIR |
❌ 硬编码 | 1 |
spawner.py:1177,1261 |
~/.openclaw/agents/<id>/sessions.json |
加 OPENCLAW_HOME |
❌ 硬编码 | 2 |
blackboard_routes.py:161 |
~/.openclaw/openclaw.json |
从 OPENCLAW_HOME 读 |
❌ 硬编码 | 1 |
共计 6 处(2 已支持、4 待修)。
环境总结
| 环境 | 位置 | 用途 | 生命周期 |
|---|---|---|---|
| 开发 | ~/.openclaw/sanguo_projects/ |
改代码、本地调试 | 常驻 |
| CI 测试 | CI runner 临时目录 | lint/unit/integration/E2E | CI 跑完即销毁 |
| 生产 | ~/.sanguo_projects/ |
正式运行服务 | 常驻 |
schema 变更检查(可选):CI 中加一步对比数据库 schema 变更,检测破坏性操作(删字段/改类型)。检测到则提 Issue 人工确认。可通过配置开关强制绕过。
§9. 完整开发流程(端到端)
9.0 全局工作流串联图
以下是把所有关键环节串起来的完整链路。三个场景(新功能/Bug修复/Hotfix)共享大部分节点,差异在分支。
┌─────────────────────────────────────────────────────────────────────────┐
│ 问题/需求入口 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 主公口头 │ │ CI 失败 │ │ 司马懿 │ │ 运行时 │ │
│ │ /需求文档 │ │ 自动报告 │ │ Review │ │ Agent发现 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ └──────────────┴──────────────┴──────────────┘ │
│ ↓ │
│ ┌─────────────────────┐ │
│ │ 需求/问题 Review │ ← §4.3 │
│ │ │ │
│ │ 需求: 庞统(方案) │ │
│ │ + 司马懿(可行) │ │
│ │ Bug: 司马懿(确认根因)│ │
│ │ Agent发现: 庞统(过滤)│ │
│ └──────────┬──────────┘ │
│ ↓ 通过 │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 创建 Gitea Issue #N │ │
│ │ 标签: bug/feature/improvement + risk:high/standard/low │ │
│ │ 关联: PR / 复现步骤 / 根因分析 │ │
│ └──────────────────────────┬────────────────────────────────┘ │
│ ↓ │
│ ┌──── 场景分流 ────┐ │
│ ↓ ↓ │
│ ┌─── Hotfix ───┐ ┌── 标准流程 ──┐ │
│ │ │ │ │ │
│ │ 直接 main │ │ 分支开发 │ │
│ │ │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ ↓ ↓ │
└─────────────────────────────────────────────────────────────────────────┘
=== 标准流程(新功能 / Bug修复)===
┌─────────────────────────────────────────────┐
│ Step 1: 分支创建 │
│ git checkout -b feat/issue-N-xxx │
│ 或 git checkout -b fix/issue-N-xxx │
│ 角色Agent: 开发者(张飞/姜维/关羽/赵云) │
│ Skill: git-workflow │
│ 输入: Issue #N │
│ 输出: feature/bugfix 分支 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 2: 编码 + 自测 │
│ 编码 → 本地 pytest → commit │
│ 角色Agent: 开发者 │
│ Skill: 按任务类型(无专门编码skill) │
│ 输入: 分支 + Issue 需求 │
│ 输出: 代码改动 + UT │
│ 约束: Bug修复必须加回归测试 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 3: push → CI 快速门控(每次push) │
│ Lint + Unit Tests │
│ 工具: Gitea Actions │
│ 输入: feature 分支 push │
│ 输出: ✅通过 / ❌失败标红 │
│ 阻断: 软阻断(失败不阻止开发,但阻止PR进入Review)│
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 4: 创建 PR │
│ git push origin → Gitea 创建 PR │
│ 自动: 风险级别标注(按改动文件路径) │
│ 工具: Gitea PR │
│ 输入: feature 分支 + CI 快速门控结果 │
│ 输出: PR + 风险标签 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 5: CI 标准门控(PR到main时) │
│ Lint + Unit + Integration + Coverage │
│ 环境: CI 隔离临时环境 │
│ 工具: Gitea Actions + pytest-cov + ruff │
│ 输入: PR diff │
│ 输出: ✅通过 / ❌阻断merge │
│ 阻断: 硬阻断(CI不过不许merge) │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 6: 代码审查 │
│ 审查者确认风险级别(只升不降) │
│ 默认审查者: 司马懿(所有级别) │
│ 例外: 司马懿的改动 → 庞统交叉审查 │
│ Skill: code-review │
│ 输入: PR + CI 结果 + 风险级别 │
│ 输出: 通过 / 不通过(附行号+修改方向) │
│ 不通过 → 回到 Step 2 │
└──────────────────┬──────────────────────────┘
↓ 通过
┌─────────────────────────────────────────────┐
│ Step 7: Merge → CI 完整门控 │
│ merge到main → 自动触发 │
│ 标准 CI + deploy workflow │
│ 触发: Gitea branch protection(CI+Review通过才许merge)│
│ 输入: main 分支 │
│ 输出: merge commit + CI 结果 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 8: 自动部署 │
│ deploy.sh --source=... --health-check │
│ 记录版本到 deploy-history.jsonl │
│ 角色Agent: 姜维(deploy.sh由项目维护) │
│ Skill: ci-cd-ops │
│ 输入: main 分支代码 │
│ 输出: 部署结果 + 版本记录 │
│ 失败: 自动回滚(deploy.sh --rollback) │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 9: E2E 验证(CI 隔离环境自动跑) │
│ 临时venv + 临时SQLite + 临时端口8084 │
│ Agent spawn 走生产 openclaw(不隔离) │
│ 角色: 司马懿写E2E用例,CI自动跑 │
│ Skill: testing-workflow │
│ 输入: 部署后的代码 │
│ 输出: E2E 结果 │
│ 阻断: 初期不阻断,成熟后可阻断 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 10: Issue 关闭 │
│ 部署成功 + 验证通过 → 关闭 Issue #N │
│ 发现新问题 → 新开 Issue → 回到入口 Review │
└─────────────────────────────────────────────┘
=== Hotfix 分支流程 ===
┌─────────────────────────────────────────────┐
│ Step H1: 确认 hotfix │
│ 庞统或主公确认(线上故障、核心功能受影响) │
│ Skill: hotfix-workflow │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step H2: 直接 push main │
│ 修改 → commit → push main │
│ CI 必须触发(lint + unit),不可跳过 │
│ CI 失败 → 自动 revert → 人工介入 │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step H3: 自动部署(同标准 Step 8) │
│ E2E 验证(同标准 Step 9) │
└──────────────────┬──────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step H4: 24h 内复盘(必须) │
│ 补 Gitea Issue(根因 + hotfix 内容) │
│ 司马懿 Review(事后审查代码质量) │
│ 复盘记录(为什么需要 hotfix、如何避免) │
│ 超时 → 下次 hotfix 权限暂停 │
└─────────────────────────────────────────────┘
衔接机制:每一步怎么触发下一步
上图只画了"谁做什么",这里补清楚步骤之间靠什么机制衔接。
| 衔接点 | 触发方式 | 通知方式 | 技术实现 |
|---|---|---|---|
| 问题入口 → 问题Review | 庞统收到问题后主动发起 | Mail 通知司马懿(需求类)/ 司马懿自己提交(bug类) | Mail API POST /api/mail |
| 问题Review → Issue创建 | Review结论达成 | 庞统或司马懿创建 | Gitea API POST /repos/{owner}/{repo}/issues |
| Issue创建 → 分支创建 | 庞统指派任务给开发者 | Mail 通知被指派者,含 Issue #N + 分支名 | Mail API + Agent 读取 Issue |
| 分支创建 → 编码 | 开发者看到 Mail 后开始 | 无额外通知 | Agent 启动时 Skill 注入分支信息 |
| 编码 → CI 快速门控 | git push 自动触发 | CI 结果显示在 commit 状态(Gitea Status Check 内置) | Gitea Actions on: push |
| CI 快速门控 → PR创建 | 开发者主动(认为代码写完) | 无自动通知 | 开发者在 Gitea Web UI 或 git push + 浏览器创建 PR |
| PR创建 → CI 标准门控 | PR 创建/更新自动触发 | CI 结果自动评论到 PR | Gitea Actions on: pull_request |
| CI 标准门控 → 代码审查 | CI 通过后 Gitea 自动通知审查者 | Gitea PR Review 请求通知 | Gitea branch protection + Reviewer 指定 |
| 代码审查 → 修改(不通过) | 审查者提交 Review 意见 | Mail 通知改动者(附 Review 摘要) | Gitea PR Review + Mail API |
| 代码审查 → Merge(通过) | 审查者点 Approve | 无额外通知 | Gitea PR Review APPROVE |
| Merge → 部署 | merge 到 main 自动触发 | 无需通知(自动化) | Gitea Actions on: push: branches: [main] |
| 部署 → E2E | 部署 job 成功后触发 E2E job | E2E 结果评论到 merge commit | Gitea Actions needs: [deploy] |
| E2E/部署 → Issue关闭 | 庞统或改动者手动确认后关闭 | Issue 关闭通知关注者 | Gitea API PATCH /repos/{owner}/{repo}/issues/{id} state=closed |
| CI失败 → Issue评论 | CI 失败自动评论 | 评论到关联 Issue | Gitea Actions if: failure() step |
| 部署失败 → 自动回滚 | deploy.sh 失败自动执行 | 无需通知(自动化) | Gitea Actions if: failure() step 调 deploy.sh --rollback |
关键衔接机制详解
1. Gitea Actions 自动触发(核心衔接)
整个 CI/CD 链路的自动化靠 Gitea Actions 的触发机制:
git push feature分支
→ Gitea Actions on: push 匹配
→ 跑 lint + unit(快速门控)
创建 PR
→ Gitea Actions on: pull_request 匹配
→ 跑 lint + unit + integration + coverage(标准门控)
→ CI 结果自动出现在 PR 页面
Merge 到 main
→ Gitea Actions on: push: branches: [main] 匹配
→ 跑 deploy workflow(含 deploy.sh + health check + E2E)
→ 全自动,无需人干预
触发链:push → CI → PR → CI → Review → merge → deploy+E2E,中间三个自动环节靠 Gitea Actions 的 on 触发器串联。
2. Mail 通知(Agent 间协调)
CI/CD 之外的衔接靠 Mail。Agent 不会自己去看 Gitea PR 评论,所以所有需要 Agent 行动的情况都通过 Mail 推送:
- 需求Review完成 → Mail 通知开发者开始
- Bug确认 → Mail 通知改动者(含根因)
- Hotfix确认 → Mail 通知执行者
- CI 失败 → Mail 通知改动者 Agent(CI workflow 里调 Mail API)
- 审查不通过 → Mail 通知改动者(附 Review 摘要)
- 部署失败回滚 → Mail 通知庞统/姜维(人工介入)
3. Gitea branch protection(硬门控)
确保流程不可跳过:
main分支设置:CI 必须通过 + 至少 1 人 Review Approve- 效果:没有 CI 绿勾 + Review Approve,merge 按钮灰色不可点
- 配置位置:Gitea → 仓库 Settings → Branches → Branch Protection
4. Agent 间通知机制总结
| 场景 | 通知方式 | 为什么不用另一种 |
|---|---|---|
| 人→Agent任务指派 | Gitea Issue 不会主动通知 Agent,需要 Mail 推送 | |
| CI 结果 | Gitea Status Check(PR页面)+ Mail(Agent通知) | Status Check 给人看,Mail 给 Agent 推送 |
| Review 请求 | Gitea Reviewer 指定 | 人(司马懿)看 Gitea |
| Review 意见不通过 | Gitea PR 评论 + Mail | 评论存档,Mail 推送 Agent |
| 跨Agent协作请求 | Gitea 不支持跨 Agent 私信 |
9.0.1 通知模板
所有自动化通知统一格式,确保 Agent 收到后能直接行动。
模板 1:任务指派(庞统 → 开发者)
From: pangtong-fujunshi
To: {被指派者}
Title: 任务指派: Issue #{N} - {Issue 标题}
Text:
{Issue 标题}
Issue: http://192.168.2.154:3000/{repo}/issues/{N}
分支: feat/issue-{N}-{简述}
风险级别: {high/standard/low}
要点:
- {需求要点1}
- {需求要点2}
验收标准:
- {验收标准1}
- {验收标准2}
模板 2:CI 失败通知(CI workflow → 改动者)
From: ci-notifier
To: {PR 作者}
Title: CI 失败: PR #{N} - {PR 标题}
Text:
PR #{N} CI 未通过。
PR: http://192.168.2.154:3000/{repo}/pulls/{N}
失败测试:
- {test_path}::{test_name} FAILED
- {test_path}::{test_name} FAILED
失败 step: {step_name}
错误摘要: {error_output_tail_20_lines}
请修复后重新 push。
模板 3:Review 不通过通知(审查者 → 改动者)
From: {审查者}
To: {改动者}
Title: Review 不通过: PR #{N} - {PR 标题}
Text:
PR #{N} 审查未通过。
PR: http://192.168.2.154:3000/{repo}/pulls/{N}
风险级别: {confirmed_level}
审查意见:
1. [{文件}:{行号}] {问题描述} → {修改方向}
2. [{文件}:{行号}] {问题描述} → {修改方向}
必须全部修改后重新 push。
模板 4:部署失败回滚通知(CI workflow → 庞统/姜维)
From: ci-notifier
To: pangtong-fujunshi, jiangwei-infra
Title: 部署失败已回滚: {repo} {commit_hash}
Text:
{repo} 部署失败,已自动回滚到上一版本。
触发 commit: {commit_hash}
部署脚本: scripts/deploy.sh
失败原因: {deploy_stderr_tail}
当前版本: {previous_version}
请人工介入排查。
模板 5:Bug 确认通知(司马懿 → 改动者)
From: simayi-challenger
To: {改动者}
Title: Bug 确认: Issue #{N} - {Issue 标题}
Text:
根因: {根因描述}
复现步骤: {steps}
影响范围: {scope}
风险级别: {level}
Issue: http://192.168.2.154:3000/{repo}/issues/{N}
分支: fix/issue-{N}-{简述}
请修复并添加回归测试。
9.1 场景 A:新功能开发
1. 问题入口
└─ 主公口头 / 需求文档
└─ 庞统梳理需求方案 → 司马懿确认技术可行性
└─ Review 通过后 → 庞统创建 Gitea Issue #N
2. 分支创建
└─ git checkout -b feat/issue-N-xxx
└─ Agent 或人工编码(git-workflow Skill 注入分支信息到 Agent 上下文)
3. 开发过程中
└─ 每个 commit → push → CI 快速门控(lint + unit)
└─ CI 失败 → 标红但不阻断开发 → 修好再 push
4. 开发完成
└─ git push origin feat/issue-N-xxx
└─ 创建 PR → 自动标注风险级别(基于改动文件路径)
└─ CI 标准门控(lint + unit + integration + coverage)
5. 审查
└─ CI 通过后进入审查
└─ 审查者确认风险级别(只升不降)
└─ 司马懿审查(所有级别默认)
└─ 如果改动者是司马懿 → 庞统交叉审查
└─ 审查不通过 → 修改 → push → CI → 再审
└─ 审查通过 → merge
6. 部署
└─ merge 到 main → 自动触发 CI + deploy workflow
└─ deploy.sh 执行 → 记录版本 → 健康检查
└─ 部署成功 → Issue #N 关闭
└─ 部署失败 → 自动回滚 → 人工介入
7. 验证
└─ CI 隔离环境中自动跑 E2E(不污染生产)
└─ 用户测试(手动)
└─ 发现问题 → 新开 Issue(经 Review 后再开发)
9.2 场景 B:Bug 修复
1. 问题入口
└─ CI 失败 / 司马懿 Review / 运行时发现
└─ 司马懿确认根因(是真 bug 不是误报)
└─ 创建 Gitea Issue #N,标注 bug + 风险级别
2. 根因定位(bugfix-workflow Skill)
└─ 调查根因(不猜,看日志/复现)
└─ 在 Issue 中记录根因
3. 修复
└─ git checkout -b fix/issue-N-xxx
└─ 修改代码 + 添加回归测试(必须)
└─ push → PR → CI → Review
4. 合并+部署
└─ merge → auto deploy → 健康检查
└─ Issue #N 关闭
5. 验证
└─ 确认原 bug 不再复现
9.3 场景 C:紧急修复(hotfix)(M1/S5 修订)
1. 判断是否需要 hotfix
└─ 标准:线上故障影响核心功能,等 PR 流程代价过高
└─ 庞统或主公确认
2. 直接在 main 上修
└─ git commit → push main
└─ CI 必须触发(lint + unit),不可跳过
└─ auto deploy → 健康检查
└─ CI 失败 → 自动 revert → 人工介入
3. 事后复盘(hotfix-workflow Skill)
└─ 24 小时内必须完成:
├─ 补 Gitea Issue(记录根因 + hotfix 内容)
├─ 司马懿 Review(事后审查代码质量)
└─ 复盘记录(为什么需要 hotfix、如何避免)
└─ 超时未复盘 → 下次 hotfix 权限暂停
4. E2E 验证
└─ CI 隔离环境中自动跑 E2E 确认 hotfix 有效
§10. Skill 清单(流程固化)(S4 修订)
以下流程通过 Skill 固化到对应 Agent:
| Skill 名 | 固化什么 | 适用 Agent |
|---|---|---|
git-workflow |
分支创建/命名/合并规范、commit 规范、PR 创建流程、当前分支注入上下文 | 所有编码 Agent |
code-review |
风险级别判定规则、审查清单(基础+项目变体)、审查标准、结论格式 | 司马懿(默认审查者)、庞统(交叉审查) |
ci-cd-ops |
CI 配置规范、deploy 脚本规范、健康检查标准、版本记录规范 | 姜维(平台)、所有项目维护者 |
bugfix-workflow |
根因定位流程、回归测试要求、Issue 关联 | 所有编码 Agent |
hotfix-workflow |
hotfix 判断标准、直接 push main 流程、CI 必跑、24h 复盘要求 | 庞统(协调)、张飞、姜维 |
testing-workflow |
测试分工规范、什么时候跑什么测试、测试数据隔离 | 所有 Agent |
release-workflow |
tag 规范、changelog、发布流程、数据库 schema 变更向前兼容规范 | 庞统(协调) |
测试分工规范(testing-workflow Skill 内)
| 测试类型 | 谁写 | 谁跑 |
|---|---|---|
| 单元测试(UT) | 开发者自己(张飞/姜维/关羽/赵云等) | CI 自动 + 开发者本地 |
| 功能测试 | 司马懿(专职) | CI 自动 |
| 集成测试 | 司马懿(专职) | CI 自动 |
| E2E 测试 | 司马懿(专职) | CI 自动(隔离环境)+ 手动触发 |
| 测试脚本/工具 | 司马懿 + 赵云(数据相关) | 按需 |
所有人都能写代码和写 UT。但功能测试、集成测试、E2E 由司马懿专职编写和维护——确保测试视角独立于开发视角。
§11. 实施路线
| 阶段 | 内容 | 前置条件 | 耗时 |
|---|---|---|---|
| P0: 基础启用 | Gitea admin 开启 Actions + 部署 act-runner(Mac mini 裸机) | 主公操作 NAS | 30 分钟 |
| P1: CI 骨架 | 模板 CI workflow + pytest-cov + ruff + 覆盖率基线测量 | P0 | 1 天 |
| P2: 流程 Skill | 7 个 Skill 编写(见 §10) | 无 | 2-3 天 |
| P3: 自动部署 | 部署 workflow + 项目 deploy.sh 规范化 + 版本记录 | P1 | 1-2 天 |
| P4: 渐进收紧 | 覆盖率阈值 P1→P2→P3、E2E 集成 | P1-P3 | 按需 |
P1 必须先就位的工具(否则机械门控跑不起来):
ruff(lint)pytest-cov(覆盖率)act-runner(CI 执行器)
§12. 评审记录
v0.1 → v0.2 修订清单
| 编号 | 类型 | 问题 | 修订内容 |
|---|---|---|---|
| M1 | 必须修 | hotfix 安全网不足 | §3.3 明确 hotfix push main 后 CI 必跑,失败自动 revert;§9.3 统一流程 |
| M2 | 必须修 | 风险级别谁来定 | §6.1 新增自动判定规则(按文件路径)+ 非改动者确认机制(只升不降) |
| M3 | 必须修 | 回滚策略过于简单 | §7.2 新增 --version 参数和 deploy-history.jsonl;§7.5 重写回滚策略 |
| M4 | 必须修 | CI 语法问题 | §5.1 删除 hasPython()/hasFrontend() 伪函数,改为每个项目按需删减 job |
| S1 | 建议改 | 轮查配对不合理 | §6.3 改为按改动领域分配,不再固定轮转 |
| S2 | 建议改 | 快速门控"不阻断"是噪音 | §5.2 改为"软阻断",PR 进入 Review 前检查最近 CI 状态 |
| S3 | 建议改 | 三阶段门控说明不清 | §8.2 补充:快速门控是开发辅助,PR 合入必须标准门控 |
| S4 | 建议改 | Skill 遗漏 | §10 增加 testing-workflow、hotfix-workflow、release-workflow(含 schema 变更) |
| S5 | 建议改 | hotfix 复盘无时限 | §9.3 加 24 小时复盘约束,超时暂停 hotfix 权限 |
| Q1 | 评审回答 | Trunk-Based 够用吗 | §3.1 补充前提:Agent 必须知道当前分支,git-workflow Skill 注入 |
| Q3 | 评审回答 | 覆盖率基线缺失 | §5.3 新增渐进策略(P1 只报告 → P2 40% → P3 60%) |
| Q6 | 评审回答 | 机械门控前提未就绪 | §8.4 新增工具清单,§11 标注 P1 必须先就位 |
v0.3 → v0.4 修订清单(主公审阅反馈)
| 编号 | 反馈 | 修订内容 |
|---|---|---|
| F1 | 需求/问题必须经 Review | §1 新增原则 7;§4.3 新增需求 Review 前置规则;§9.1 场景 A 加入 Review 步骤 |
| F2 | E2E 仅用户触发 | §8.1 E2E 改为“仅用户手动触发”;§8.2 门控说明移除 E2E 自动跑;§9.1/9.3 验证步骤更新 |
| F3 | 编码/测试人人能做,功能/集成/E2E 司马懿专职 | §10 新增测试分工规范表 |
| F4 | 审查默认司马懿 | §6.2 简化为司马懿统一审查,仅司马懿自身改动由庞统交叉审查 |
| F5 | 以项目为单位组织 | §1 新增原则 8;Issue 标签体系含项目维度 |
| F6 | 姜维持有 Gitea admin | §2.1 权限更新 |
| F7 | 分支保护含义说明 | §3.3 补充分支保护规则说明 |
| F8 | schema 变更能自动化就自动化 | 保留在 release-workflow,CI check + Issue 兜底 |
v0.4 → v0.5 修订清单(主公二次审阅)
| 编号 | 反馈 | 修订内容 |
|---|---|---|
| G1 | E2E 不自动跑是因为怕污染生产,不是不需要 | §8.5 新增 CI 隔离测试环境,E2E 改为自动跑(临时 venv + 临时 SQLite + 临时端口) |
| G2 | 三套环境是否有必要 | §8.5 环境总结表:开发/CI临时/生产,不需要常驻测试环境 |
| G3 | schema 变更检查可以,可选+开关 | §8.5 补充 schema 检查说明:可选 + 配置开关强制绕过 |
| G4 | 分支保护确认开启 | §14 更新为已确认 |
| G5 | E2E 触发方式 | §8.1 更新:CI 自动 + 手动触发 |
v0.5 → v0.6 修订清单(主公三次审阅)
| 编号 | 反馈 | 修订内容 |
|---|---|---|
| H1 | Agent spawn 走生产 openclaw,不隔离 | §8.5 新增隔离边界表:程序逻辑隔离 vs Agent 走生产 |
| H2 | 路径硬编码问题 | §8.5 新增路径硬编码修复清单(6 处,2 处已支持、4 处待修) |
v0.6 → v1.0 定稿(司马懿终审通过)
- 隔离边界表增加"缓解措施"列(仲达建议)
- 路径硬编码清单增加"行数"列(仲达建议)
- 状态标记为 v1.0 定稿
v1.0 → v1.1(主公要求:补全局工作流串联图)
- §9.0 新增全局工作流串联图:从问题入口到部署上线的完整链路
- 每个节点标注:谁做、用什么工具、什么Skill、输入输出
- 标准流程 10 步 + Hotfix 分支 4 步
- 新增工具链衔接总览表
- 新增衔接机制详解:每一步怎么触发下一步、靠什么技术、怎么通知
- §9.0.1 新增 5 个通知模板(任务指派/CI失败/Review不通过/部署回滚/Bug确认)
- 修正:Agent 不看 Gitea PR 评论,所有需 Agent 行动的场景都走 Mail 推送
§13. 项目维度组织
13.1 多项目并行
所有内容以项目为单位组织:
| 维度 | 按项目组织 |
|---|---|
| 代码仓库 | Gitea 上每个项目一个 repo |
| Issue | 每个项目的 Issue 独立管理 |
| CI/CD | 每个项目自管 .gitea/workflows/ |
| 部署脚本 | 每个项目自管 scripts/deploy.sh |
| 测试 | 每个项目自管 tests/ 目录 |
| Skill 配置 | 通用 Skill 共享,项目特定 Skill 放项目仓库 |
特殊:_general 项目用于跨项目的通用任务(如工具链基础设施维护)。
§14. 待讨论
- Gitea admin 权限:姜维持有 admin 权限,可负责启用 Actions、配置分支保护等
- 分支保护:已确认开启——PR 必须 CI 通过 + 至少 1 人 Review 才能合并到 main
- 数据库 schema 变更检查:CI 自动检测破坏性变更(可选,有开关可强制绕过),检测不到的提 Issue 人工干预
- 环境架构:三环境(开发/CI临时/生产),CI 临时环境支持 E2E 自动跑不污染生产