feat: Gitea 协作规范落地 — 标题前缀+Label+模板+L2注入
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
name: Bug 报告
|
||||||
|
about: 报告一个 Bug
|
||||||
|
title: "[moz] bug: "
|
||||||
|
labels:
|
||||||
|
- type/bug
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Bug 描述
|
||||||
|
description: 清晰描述什么行为是错误的
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduce
|
||||||
|
attributes:
|
||||||
|
label: 复现步骤
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: 预期行为
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: priority
|
||||||
|
attributes:
|
||||||
|
label: 优先级
|
||||||
|
options:
|
||||||
|
- P0 紧急
|
||||||
|
- P1 高
|
||||||
|
- P2 中
|
||||||
|
- P3 低
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
name: 功能需求
|
||||||
|
about: 提出一个新功能需求
|
||||||
|
title: "[moz] feat: "
|
||||||
|
labels:
|
||||||
|
- type/feat
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: 需求描述
|
||||||
|
description: 你希望实现什么功能?为什么需要?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: 建议方案
|
||||||
|
description: 如果有初步想法可以写 here
|
||||||
|
- type: dropdown
|
||||||
|
id: priority
|
||||||
|
attributes:
|
||||||
|
label: 优先级
|
||||||
|
options:
|
||||||
|
- P0 紧急
|
||||||
|
- P1 高
|
||||||
|
- P2 中
|
||||||
|
- P3 低
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
name: 测试任务
|
||||||
|
about: 创建一个测试任务(E2E、集成测试等)
|
||||||
|
title: "[moz] test: "
|
||||||
|
labels:
|
||||||
|
- type/test
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: 测试目标
|
||||||
|
description: 要验证什么场景?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: steps
|
||||||
|
attributes:
|
||||||
|
label: 测试步骤
|
||||||
|
description: 关键步骤或验收标准
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
## 改动概述
|
||||||
|
|
||||||
|
<!-- 一句话说明这个 PR 做了什么 -->
|
||||||
|
|
||||||
|
## 关联 Issue
|
||||||
|
|
||||||
|
<!-- #issue_number,如果没有关联可删掉 -->
|
||||||
|
|
||||||
|
## 改动类型
|
||||||
|
|
||||||
|
- [ ] feat: 新功能
|
||||||
|
- [ ] impl: 实现
|
||||||
|
- [ ] fix: 修复
|
||||||
|
- [ ] docs: 文档
|
||||||
|
- [ ] test: 测试
|
||||||
|
- [ ] refactor: 重构
|
||||||
|
- [ ] ci: CI/CD
|
||||||
|
- [ ] chore: 杂项
|
||||||
|
|
||||||
|
## 检查清单
|
||||||
|
|
||||||
|
- [ ] 标题格式正确:`[代号] type(scope): 简述`
|
||||||
|
- [ ] 改动在开发目录(`~/.openclaw/sanguo_projects/`)完成
|
||||||
|
- [ ] 已同步到安装目录(`~/.sanguo_projects/`)
|
||||||
|
- [ ] 已运行测试(如适用)
|
||||||
|
- [ ] 已更新相关设计文档(如适用)
|
||||||
@@ -245,11 +245,14 @@ pm2 show sanguo-act-runner # 详情
|
|||||||
|------|------|
|
|------|------|
|
||||||
| `feat` | 新功能 |
|
| `feat` | 新功能 |
|
||||||
| `fix` | Bug 修复 |
|
| `fix` | Bug 修复 |
|
||||||
|
| `impl` | 按设计文档实现 |
|
||||||
| `refactor` | 重构(不改行为) |
|
| `refactor` | 重构(不改行为) |
|
||||||
| `test` | 测试相关 |
|
| `test` | 测试相关 |
|
||||||
| `docs` | 文档 |
|
| `docs` | 文档 |
|
||||||
| `chore` | 构建/工具/配置 |
|
| `chore` | 构建/工具/配置 |
|
||||||
|
|
||||||
|
sanguo 组织所有仓库统一使用此 commit 规范。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## §4. 问题管理
|
## §4. 问题管理
|
||||||
@@ -266,15 +269,19 @@ pm2 show sanguo-act-runner # 详情
|
|||||||
|
|
||||||
### 4.2 Issue 标签体系
|
### 4.2 Issue 标签体系
|
||||||
|
|
||||||
| 标签 | 颜色 | 说明 |
|
| 标签 | 颜色 | 色值 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|------|
|
||||||
| `bug` | 红 | 功能异常 |
|
| `type/bug` | 红 | #ee0701 | Bug 修复 |
|
||||||
| `feature` | 蓝 | 新功能需求 |
|
| `type/feat` | 蓝 | #84b6eb | 新功能 |
|
||||||
| `improvement` | 绿 | 改进优化 |
|
| `type/impl` | 浅蓝 | #c5def5 | 按设计实现 |
|
||||||
| `security` | 橙 | 安全相关 |
|
| `type/docs` | 黄 | #fbca04 | 文档 |
|
||||||
| `risk:high/standard/low` | 分级色 | 风险级别(见 §6.1 判定规则) |
|
| `type/test` | 绿 | #0e8a16 | 测试 |
|
||||||
| `priority:high/medium/low` | 黄/灰 | 优先级 |
|
| `type/ci` | 紫 | #d4c5f9 | CI/CD |
|
||||||
| `blocked` | 紫 | 阻塞中 |
|
| `type/refactor` | 橙 | #ff6f00 | 重构 |
|
||||||
|
| `priority/P0` | 深红 | #b60205 | 紧急 |
|
||||||
|
| `priority/P1` | 红 | #d93f0b | 高 |
|
||||||
|
| `priority/P2` | 黄 | #fbca04 | 中 |
|
||||||
|
| `priority/P3` | 浅蓝 | #c5def5 | 低 |
|
||||||
|
|
||||||
### 4.3 需求/问题 Review 前置
|
### 4.3 需求/问题 Review 前置
|
||||||
|
|
||||||
@@ -296,6 +303,29 @@ Open → In Progress → Review → Closed
|
|||||||
└──── Reopened ←───────────────────┘
|
└──── Reopened ←───────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 4.5 标题规范
|
||||||
|
|
||||||
|
所有 Issue 和 PR 标题**必须**包含项目代号前缀,让人类一眼识别项目+类型:
|
||||||
|
|
||||||
|
**Issue**: `[代号] type: 简述`
|
||||||
|
**PR**: `[代号] type(scope): 简述`
|
||||||
|
|
||||||
|
项目代号:
|
||||||
|
|
||||||
|
| 仓库 | 代号 |
|
||||||
|
|------|------|
|
||||||
|
| sanguo_moziplus_v2 | moz |
|
||||||
|
| sanguo_quant_live | quant |
|
||||||
|
| sanguo_vnpy | vnpy |
|
||||||
|
|
||||||
|
示例:
|
||||||
|
- `[moz] bug: Mail API 500 when comment_type invalid`
|
||||||
|
- `[moz] impl(daemon): 知识注入 L2 引擎层 — WikiGuideSection`
|
||||||
|
- `[quant] feat: 趋势跟踪策略骨架`
|
||||||
|
|
||||||
|
此规范通过 L2 引擎层 `GiteaConventionSection`(priority=55)自动注入所有 Agent prompt。
|
||||||
|
完整规范文档:L3 Skill `gitea-conventions`。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## §5. CI/CD 管道设计
|
## §5. CI/CD 管道设计
|
||||||
@@ -3297,3 +3327,48 @@ async def _handle_issue_comment(payload):
|
|||||||
|------|------|------|
|
|------|------|------|
|
||||||
| 2026-06-09 | v1.0 | 初版:E2E 真实场景暴露问题 → 四层改造方案 + @mention 通知 + Mail type 改造 |
|
| 2026-06-09 | v1.0 | 初版:E2E 真实场景暴露问题 → 四层改造方案 + @mention 通知 + Mail type 改造 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## §26. Gitea 协作规范落地
|
||||||
|
|
||||||
|
> **状态**: ✅ 已完成
|
||||||
|
> **日期**: 2026-06-14
|
||||||
|
> **PR**: 本次改动随 PR 提交
|
||||||
|
|
||||||
|
### 26.1 动机
|
||||||
|
|
||||||
|
团队三个仓库(moziplus_v2 / quant_live / vnpy)缺少统一的 Issue/PR 模板、Label 体系和标题规范。人类从标题无法一眼分辨是哪个项目什么类型的问题。
|
||||||
|
|
||||||
|
### 26.2 落地内容
|
||||||
|
|
||||||
|
| 层级 | 内容 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| L3 | `gitea-conventions` Skill | 完整规范文档(标题/分支/commit/label) |
|
||||||
|
| L2 | `GiteaConventionSection`(priority=55) | 注入所有 handler(task/toolchain/mail),自动提醒 Agent 遵循标题格式 |
|
||||||
|
| L1 | TOOLS.md 追加代号表 | Agent 静态可见的速查 |
|
||||||
|
| Gitea 模板 | 3 仓库 × 4 文件 | bug.yml / feature.yml / test.yml / PULL_REQUEST_TEMPLATE.md |
|
||||||
|
| Gitea Labels | 3 仓库 × 11 个 | type × 7 + priority × 4 |
|
||||||
|
|
||||||
|
### 26.3 四层注入路径
|
||||||
|
|
||||||
|
```
|
||||||
|
L1 TOOLS.md(静态,Agent workspace)
|
||||||
|
→ 代号表 + 格式速查
|
||||||
|
|
||||||
|
L2 GiteaConventionSection(动态,每次 spawn 注入)
|
||||||
|
→ "创建 Issue/PR 时标题必须带 [代号] 前缀"
|
||||||
|
|
||||||
|
L3 gitea-conventions Skill(被动,extraDirs 自动发现)
|
||||||
|
→ 完整规范:标题/分支/commit/label/模板
|
||||||
|
```
|
||||||
|
|
||||||
|
### 26.4 代码改动
|
||||||
|
|
||||||
|
| 文件 | 改动 |
|
||||||
|
|------|------|
|
||||||
|
| `prompt_composer.py` | 新增 `GiteaConventionSection`(priority=55) |
|
||||||
|
| `task_handler.py` | `get_sections()` 注册 `GiteaConventionSection()` |
|
||||||
|
| `toolchain_handler.py` | `get_sections()` 注册 `GiteaConventionSection()` |
|
||||||
|
| `mail_handler.py` | `get_sections()` 注册 `GiteaConventionSection()` |
|
||||||
|
| `db.py` | `COMMENT_TYPES` 补 `action_report`(修 API 500 bug) |
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ VALID_TRANSITIONS = {
|
|||||||
COMMENT_TYPES = frozenset({
|
COMMENT_TYPES = frozenset({
|
||||||
"general", "handoff", "observation", "review", "rebuttal",
|
"general", "handoff", "observation", "review", "rebuttal",
|
||||||
"rebuttal_response", "debate_argument", "debate_rebuttal", "debate_judgment",
|
"rebuttal_response", "debate_argument", "debate_rebuttal", "debate_judgment",
|
||||||
|
"action_report",
|
||||||
})
|
})
|
||||||
|
|
||||||
SEVERITY_LEVELS = frozenset({"blocking", "warning", "info", "audit"})
|
SEVERITY_LEVELS = frozenset({"blocking", "warning", "info", "audit"})
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
|
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
|
||||||
from src.daemon.prompt_composer import PromptComposer, PromptContext, WikiGuideSection
|
from src.daemon.prompt_composer import PromptComposer, PromptContext, GiteaConventionSection, WikiGuideSection
|
||||||
from src.blackboard.db import get_connection
|
from src.blackboard.db import get_connection
|
||||||
|
|
||||||
logger = logging.getLogger("moziplus-v2.handler.mail")
|
logger = logging.getLogger("moziplus-v2.handler.mail")
|
||||||
@@ -36,7 +36,7 @@ class MailHandler(BaseTaskHandler):
|
|||||||
return composer.compose(context)
|
return composer.compose(context)
|
||||||
|
|
||||||
def get_sections(self) -> list:
|
def get_sections(self) -> list:
|
||||||
return [MailContextSection(), MailApiSection(), MailConstraintsSection(), WikiGuideSection()]
|
return [MailContextSection(), MailApiSection(), MailConstraintsSection(), GiteaConventionSection(), WikiGuideSection()]
|
||||||
|
|
||||||
def verify_completion(self, task_id: str, db_path: Path) -> VerifyResult:
|
def verify_completion(self, task_id: str, db_path: Path) -> VerifyResult:
|
||||||
"""Mail 完成验证:区分 inform/request。
|
"""Mail 完成验证:区分 inform/request。
|
||||||
|
|||||||
@@ -129,6 +129,29 @@ class PromptComposer:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
class GiteaConventionSection:
|
||||||
|
"""Gitea 标题规范引导段 — 提醒 Agent 创建 Issue/PR 时遵循标题格式。"""
|
||||||
|
|
||||||
|
name: str = "gitea_convention"
|
||||||
|
priority: int = 55 # CONSTRAINTS(50) 和 EXTENSION(60) 之间
|
||||||
|
|
||||||
|
CONVENTION_TEXT = (
|
||||||
|
"## Gitea 标题规范\n"
|
||||||
|
"创建 Issue/PR 时,标题**必须**包含项目代号前缀:\n"
|
||||||
|
"- Issue: `[代号] type: 简述`,如 `[moz] bug: Mail API 500`\n"
|
||||||
|
"- PR: `[代号] type(scope): 简述`,如 `[moz] impl(daemon): WikiGuideSection 注入`\n"
|
||||||
|
"代号:moz=moziplus_v2, quant=quant_live, vnpy=vnpy\n"
|
||||||
|
"type: bug/feat/impl/fix/docs/test/ci/refactor/chore"
|
||||||
|
)
|
||||||
|
|
||||||
|
def render(self, context: "PromptContext") -> str:
|
||||||
|
return self.CONVENTION_TEXT
|
||||||
|
|
||||||
|
def should_include(self, context: "PromptContext") -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# WikiGuideSection — 知识查询引导段
|
# WikiGuideSection — 知识查询引导段
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from pathlib import Path
|
|||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
|
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
|
||||||
from src.daemon.prompt_composer import PromptComposer, PromptContext, WikiGuideSection
|
from src.daemon.prompt_composer import PromptComposer, PromptContext, GiteaConventionSection, WikiGuideSection
|
||||||
from src.blackboard.db import get_connection
|
from src.blackboard.db import get_connection
|
||||||
|
|
||||||
logger = logging.getLogger("moziplus-v2.handler")
|
logger = logging.getLogger("moziplus-v2.handler")
|
||||||
@@ -306,13 +306,14 @@ class TaskHandler(BaseTaskHandler):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def get_sections(self) -> list:
|
def get_sections(self) -> list:
|
||||||
"""返回 5 个 PromptSection 实例。"""
|
"""返回 PromptSection 实例。"""
|
||||||
return [
|
return [
|
||||||
TaskContextSection(),
|
TaskContextSection(),
|
||||||
PriorOutputsSection(),
|
PriorOutputsSection(),
|
||||||
RoleSkillSection(),
|
RoleSkillSection(),
|
||||||
TaskApiSection(),
|
TaskApiSection(),
|
||||||
TaskConstraintsSection(),
|
TaskConstraintsSection(),
|
||||||
|
GiteaConventionSection(),
|
||||||
WikiGuideSection(),
|
WikiGuideSection(),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
|||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
|
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
|
||||||
from src.daemon.prompt_composer import PromptComposer, PromptContext, WikiGuideSection
|
from src.daemon.prompt_composer import PromptComposer, PromptContext, GiteaConventionSection, WikiGuideSection
|
||||||
from src.daemon.toolchain_templates import render_template, _TEMPLATE_MAP
|
from src.daemon.toolchain_templates import render_template, _TEMPLATE_MAP
|
||||||
from src.blackboard.db import get_connection
|
from src.blackboard.db import get_connection
|
||||||
|
|
||||||
@@ -221,11 +221,12 @@ class ToolchainHandler(BaseTaskHandler):
|
|||||||
return self._auto_mark_working(task_id, db_path)
|
return self._auto_mark_working(task_id, db_path)
|
||||||
|
|
||||||
def get_sections(self) -> list:
|
def get_sections(self) -> list:
|
||||||
"""返回 3 个 Toolchain PromptSection 实例"""
|
"""返回 Toolchain PromptSection 实例"""
|
||||||
return [
|
return [
|
||||||
ToolchainContextSection(),
|
ToolchainContextSection(),
|
||||||
ToolchainApiSection(),
|
ToolchainApiSection(),
|
||||||
ToolchainConstraintsSection(),
|
ToolchainConstraintsSection(),
|
||||||
|
GiteaConventionSection(),
|
||||||
WikiGuideSection(),
|
WikiGuideSection(),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user