Files
sanguo_moziplus_v2/docs/design/13-toolchain-and-dev-workflow.md
T
2026-06-06 08:40:18 +08:00

921 lines
44 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 三国团队工具链与开发流程设计
> **状态**: 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/CDGitea Actions
| 项 | 配置 |
|----|------|
| Runner | Mac mini 裸机,act-runnerGo 二进制) |
| 配置文件 | `.gitea/workflows/*.yml`,每个项目自管 |
| 语法 | 兼容 GitHub Actionsv1.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` 分支:
- 不允许直接 pushhotfix 除外)
- PR 必须通过 CI(至少 unit + integration tests
- PR 必须至少 1 人 Review(人或 Agent
- **hotfix 直接 push main 后必须触发 CI**(至少 lint + unit),CI 失败则自动 revertM1 修订)
- 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 修订)
```yaml
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 | 标准 + buildE2E 仅 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 |
**确认机制**
1. PR 创建时自动标注风险级别(基于 git diff 文件路径)
2. 审查者(或庞统)确认或升级——**只能升级不能降级**
3. 改动者可以申请升级(但不能申请降级)
### 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`,接口统一:
```bash
#!/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
```yaml
# .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
**回滚流程**
1. `deploy.sh --rollback` 读取上一个成功版本
2. `git checkout <previous-commit>`
3. 重新执行 deploy(不含 rollback
4. 健康检查
**已知限制**
- 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 新建)
├─ 临时 SQLitetmpdir,跑完销毁)
├─ 临时端口(8084,不和生产 8083 冲突)
├─ 启动 FastAPI 服务 → 跑 E2E → 关闭
└─ 跑完整个 tmpdir 删除,不留痕迹
生产环境(~/.sanguo_projects/)完全不受影响
```
**效果**E2E 可以在每次 PR 到 main 时自动跑,无需担心污染生产数据或影响生产服务。
#### 隔离边界:程序逻辑 vs Agent 交互
| 层面 | 隔离方式 | 说明 |
|------|---------|------|
| **程序逻辑**FastAPI + Daemon + SQLite | ✅ 完全隔离 | 独立 venv + 临时数据库 + 临时端口 | — |
| **Agent spawn**openclaw agent | ❌ 走生产 openclaw | openclaw 是全局单例,无法隔离 | 测试 case 用 UUID 前缀标识 + Agent 回写地址指向 8084 临时端口 |
Agent spawn 走生产 openclaw 的决策理由:
1. openclaw 是全局单例(`~/.openclaw/` 只有一份),Agent 配置和 workspace 全局共享
2. 测试 case 会标识测试上下文,Agent 记忆混淆风险低
3. 完全隔离需要在 Docker 中跑独立 openclaw,维护成本不值得
4. 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 protectionCI+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 权限暂停 │
└─────────────────────────────────────────────┘
```
#### 工具链衔接总览
| 环节 | 工具 | Agent/人 | Skill | 输入 | 输出 |
|------|------|---------|-------|------|------|
| 问题Review | Mail/口头 | 庞统+司马懿 | — | 问题描述 | 确认的需求/bug |
| Issue创建 | Gitea Issues | 庞统/司马懿 | — | 确认的问题 | Issue #N + 标签 |
| 分支创建 | git | 开发者 | git-workflow | Issue #N | feature/bugfix 分支 |
| 编码+UT | 本地IDE | 开发者 | — | 分支+需求 | 代码+UT |
| CI 快速门控 | Gitea Actions | 自动 | ci-cd-ops | push | lint+unit 结果 |
| PR创建 | Gitea PR | 开发者 | git-workflow | 分支+CI结果 | PR+风险标签 |
| CI 标准门控 | Gitea Actions | 自动 | ci-cd-ops | PR diff | 全套CI结果 |
| 代码审查 | Gitea PR Review | 司马懿 | code-review | PR+CI结果 | 通过/不通过 |
| Merge | Giteabranch protection | 自动 | — | Review通过+CI通过 | merge commit |
| 部署 | deploy.sh | 自动 | ci-cd-ops | main代码 | 部署结果+版本 |
| E2E验证 | pytestCI隔离) | 司马懿写/CI跑 | testing-workflow | 部署代码 | E2E结果 |
| Issue关闭 | Gitea Issues | 庞统/改动者 | — | 部署+验证通过 | Issue Closed |
### 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 场景 BBug 修复
```
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-runnerMac 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-workflowCI 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 步
- 新增工具链衔接总览表
---
## §13. 项目维度组织
### 13.1 多项目并行
所有内容以项目为单位组织:
| 维度 | 按项目组织 |
|------|------------|
| **代码仓库** | Gitea 上每个项目一个 repo |
| **Issue** | 每个项目的 Issue 独立管理 |
| **CI/CD** | 每个项目自管 `.gitea/workflows/` |
| **部署脚本** | 每个项目自管 `scripts/deploy.sh` |
| **测试** | 每个项目自管 `tests/` 目录 |
| **Skill 配置** | 通用 Skill 共享,项目特定 Skill 放项目仓库 |
特殊:`_general` 项目用于跨项目的通用任务(如工具链基础设施维护)。
---
## §14. 待讨论
1. **Gitea admin 权限**:姜维持有 admin 权限,可负责启用 Actions、配置分支保护等
2. **分支保护**:已确认开启——PR 必须 CI 通过 + 至少 1 人 Review 才能合并到 main
3. **数据库 schema 变更检查**:CI 自动检测破坏性变更(可选,有开关可强制绕过),检测不到的提 Issue 人工干预
4. **环境架构**:三环境(开发/CI临时/生产),CI 临时环境支持 E2E 自动跑不污染生产