Merge pull request #193 from openqj/feat-software-engineering-github
feat: software-engineering skill GitHub guarantees
This commit is contained in:
2 files changed
+158
-1
No files matched your search
@@ -81,7 +81,8 @@ G4 分阶段不是“慢”,是止损:web 先行验证核心链路和契约
|
||||
|
||||
| 门 | 名称 | 通过标准 | 没通过怎么办 |
|
||||
|----|------|----------|--------------|
|
||||
| G0 | 接单选型冻结 | 客户端清单、目标用户、核心能力、MVP 范围、路线(真原生 / 跨平台壳 + Web 核心)都已由用户确认;**且 agent 类产品必须同时确认执行模型、权限边界、审批模型**(见下) | 不开任何开发线程,继续问 |
|
||||
| G0 | 接单选型冻结 | 客户端清单、目标用户、核心能力、MVP 范围、路线(真原生 / 跨平台壳 + Web 核心)都已由用户确认;**且 agent 类产品必须同时确认执行模型、权限边界、审批模型**(见下);**且仓库冻结项已确认:仓库是新建还是已有、GitHub owner/repo、默认分支、可见性** | 不开任何开发线程,继续问 |
|
||||
| G0.5 | 建仓完成 | 新产品已建仓且首 commit 已落默认分支(首 commit 只含仓库骨架,不含业务代码);已有仓库已核对 owner/repo、默认分支、可见性与 PRD 一致 | G1 不开始,先建仓或先改 PRD |
|
||||
| G1 | PRD 冻结 | PRD 按 `templates/artifacts/prd-outline.md` 写完,用户故事有验收标准,不做清单已写明;**agent 类产品必须有能力边界、失败故事、成本故事三节** | 回产品线程改,不进入设计 |
|
||||
| G2 | 契约冻结 | API 契约、数据模型、agent 协议、错误码、鉴权方式已定稿,版本号为 v1;**且必须有任务状态机、错误 taxonomy、技术栈表、每端能力矩阵四份冻结物** | 客户端线程不准开工 |
|
||||
| G3 | 共享核心完成 | 共享类型、API SDK、鉴权与同步逻辑可被客户端引用,有单测;**且有可跑的 mock 服务和契约测试** | 客户端线程等共享线程,不自己各写一套 |
|
||||
@@ -112,6 +113,12 @@ G4 分阶段不是“慢”,是止损:web 先行验证核心链路和契约
|
||||
G0 的六问缺一问,G0 就不算过。用户没回复时,协调员等,不按假设推进,
|
||||
状态保存在待办里。
|
||||
|
||||
建仓是 G0 之后、G1 之前的前置任务,不是 G1 里的顺带事:
|
||||
新产品先建仓,首 commit 只含仓库骨架(README、.gitignore、目录骨架),
|
||||
不含业务代码,首 commit 落到默认分支后,后续业务工作一律走分支加 PR;
|
||||
已有仓库先核对 owner/repo、默认分支(以仓库实际 default_branch 为准,不猜)、
|
||||
可见性与 PRD 一致,不一致先改 PRD 或换仓库,不要边开发边改仓库地址。
|
||||
|
||||
## 角色线程矩阵
|
||||
|
||||
| 角色 | 线程数 | 负责目录 | 产出 |
|
||||
@@ -221,6 +228,69 @@ tests/ # QA 线程专属,含跨端一致性用例
|
||||
检查,确认本分支只改了拥有目录(契约变更经批准的除外)。
|
||||
在 Docker 任务共享工作目录的环境里,这一步尤其不能省。
|
||||
|
||||
## GitHub 保证(每线程一分支、一 PR、一合并门)
|
||||
|
||||
本节是 GitHub 层面的硬规则,与上面的目录隔离、协调员评审并行生效,
|
||||
两者缺一不可。下面的规则同样写进了附录的协调员、客户端、验收章节,
|
||||
正文与附录不一致就是不合格,发布前必须核对。
|
||||
|
||||
### 分支:每线程一分支,绝不直接推默认分支
|
||||
|
||||
- 命名沿用 `feat/swe/<阶段>-<角色>-<简称>`,例如 `feat/swe/client-web`。
|
||||
分支名即任务归属,禁止两个线程共用一个分支改同一目录。
|
||||
- 绝不直接推默认分支,绝不对默认分支 force-push。
|
||||
本地落后主线时,先同步主线到自己的分支(fetch 后 rebase 或 merge,
|
||||
以仓库约定为准,协调员派生时写清用哪一种),再推分支提 PR;
|
||||
冲突由协调员判定,不静默解决后推。
|
||||
|
||||
### PR 交付:没有 PR 号不算完成
|
||||
|
||||
- 每线程交付必须含 PR:推分支、建 PR、请协调员评审。
|
||||
PR 正文必须写清:范围(改了哪个拥有目录)、契约版本、
|
||||
测试证据(命令与结果)、已知问题、关联的待办项或 PRD 项。
|
||||
- 没有 PR 号的交付不算完成。协调员收到“做完了但没 PR”时打回补 PR,
|
||||
不先评审代码。PR 里的评审意见必须逐条处理或明确回复,
|
||||
未解决的评审意见不能合并。
|
||||
|
||||
### 合并门:缺一不可,与主分支保护
|
||||
|
||||
- 合并前四项全过:① GitHub Checks 全绿;② 目录归属检查通过
|
||||
(只改拥有目录,契约变更经批准除外);③ 契约版本是冻结版;
|
||||
④ 协调员评审通过,且无未解决评审意见。有一项不过就不合并。
|
||||
- CI 怎么查:用只读方式查,例如本平台的 GET /tasks/{id}/pr/checks。
|
||||
它是只读诊断,绝不重跑检查、不批准、不合并;还没建 PR 时它会 409
|
||||
(查无可查),这时先补 PR,不要把它当成 CI 通过。
|
||||
- 主分支保护(GitHub 仓库设置,不是本平台代码能替你开的):
|
||||
要求 PR、要求 CI 通过、禁止直接推。目标仓库没开保护时,
|
||||
协调员要在决策记录里写明风险并去开通,不能假装已保护,
|
||||
不能靠“大家自觉”代替保护。
|
||||
|
||||
### 合并方式与合并记录
|
||||
|
||||
- 默认 merge commit,不用 squash 或 rebase 改写分支历史口径
|
||||
(仓库另有约定且协调员记录在案时除外)。
|
||||
- 合并记录必须含:PR 号、合并提交 hash、CI 运行链接、执行人。
|
||||
执行人是人或宿主操作,不是“协调员任务自己合”。
|
||||
- 合并后删远程分支(本地分支同步清理),避免旧分支被误复用;
|
||||
删分支前确认合并提交已在主线。
|
||||
|
||||
### 发布与回滚:按端打 tag,绝不 force-push 回退
|
||||
|
||||
- 按端发布时打 tag,例如 v0.1.0;发布说明从已合 PR 汇总,不凭记忆重写。
|
||||
- 回滚是 revert 对应 PR,或重部署上一个 tag;绝不是 force-push 回退主线。
|
||||
回滚后要重新走合并门(CI、评审)才能再发布,不要回滚完直接推。
|
||||
|
||||
### 安全:密钥绝不进代码、commit、命令行
|
||||
|
||||
- 密钥、口令、token 绝不进代码、commit、命令行、PR 正文、日志。
|
||||
需要调用 GitHub 时,token 只进子进程环境(本仓库 cloud/pr.py 的做法
|
||||
就是 token 只进子进程环境变量 GIT_TOKEN,不进命令行参数、不进远端 URL),
|
||||
不要把 token 写进示例命令。
|
||||
- 新产品仓库的 .gitignore 必须覆盖密钥文件与本地配置文件
|
||||
(例如 .env、本地凭据、本地配置),首 commit 前由协调员检查 .gitignore 在位;
|
||||
已发现密钥进了 commit 时,按仓库的密钥轮换流程处理并记录,
|
||||
不靠改写历史掩盖(已公开的历史不能靠改写抹掉)。
|
||||
|
||||
## 测试与验收
|
||||
|
||||
- 每个客户端线程交付前必须自测:单元测试 + 对接契约的集成测试
|
||||
@@ -271,6 +341,11 @@ tests/ # QA 线程专属,含跨端一致性用例
|
||||
- 每个客户端的交付物里,有没有把“未验证”写成“已完成”?
|
||||
- 待办文件是不是协调员唯一维护的最新状态?有没有子线程直接改了待办?
|
||||
- 合并记录里执行人写了吗?是协调员评审 + 人 / 宿主执行,还是冒充成协调员自己合的?
|
||||
- GitHub 门全过了吗?每线程交付有 PR 号吗?Checks 全绿吗?目录归属过了吗?
|
||||
主分支保护开了吗,没开有没有记为风险?合并是 merge commit 吗?
|
||||
合并记录里 PR 号、合并提交 hash、CI 运行链接齐了吗?合并后删远程分支了吗?
|
||||
发布打 tag 了吗,回滚方案是 revert 或重部署上一 tag、而不是 force-push 吗?
|
||||
密钥进代码、commit、命令行了吗?.gitignore 在首 commit 前检查了吗?
|
||||
- 验收清单是不是用户亲手确认的?有没有一项是协调员替用户勾的?
|
||||
- 分阶段走了吗?G3.5 没过就开了 G4b / G4c 吗?
|
||||
有一项为否,就停在当前门禁,不进入下一阶段。
|
||||
@@ -353,6 +428,35 @@ tests/ # QA 线程专属,含跨端一致性用例
|
||||
|
||||
---
|
||||
|
||||
|
||||
## GitHub 保证(协调员)
|
||||
|
||||
- 建仓:G0 之后、G1 之前做。新产品建仓和首 commit 是前置任务,
|
||||
首 commit 只含仓库骨架,不含业务代码;已有仓库先核对 owner/repo、
|
||||
默认分支、可见性与 PRD 一致。仓库冻结项(新建还是已有、owner/repo、
|
||||
默认分支、可见性)缺一项,G0 不算过。
|
||||
- 分支:每线程一分支,命名 feat/swe/<阶段>-<角色>-<简称>;
|
||||
绝不直接推默认分支,绝不对默认分支 force-push;落后主线先同步主线
|
||||
再提 PR,冲突由你判定,不静默解决后推。
|
||||
- PR 交付:没有 PR 号不算完成。PR 正文必须有范围、契约版本、
|
||||
测试证据、已知问题、关联待办或 PRD 项;评审意见逐条处理,
|
||||
未解决的评审意见不能合并。
|
||||
- 合并门:GitHub Checks 全绿、目录归属检查通过、契约版本是冻结版、
|
||||
你评审通过且无未解决评审意见,四项缺一不可。
|
||||
CI 用只读方式查,例如 GET /tasks/{id}/pr/checks,它绝不重跑检查、
|
||||
不批准、不合并;无 PR 时它会 409,先补 PR。
|
||||
- 主分支保护:要求 PR、要求 CI 通过、禁止直接推,这是 GitHub 仓库设置,
|
||||
不是本平台代码能替你开的。没开保护时记为风险并去开通,不假装已保护。
|
||||
- 合并记录:默认 merge commit;记录必须含 PR 号、合并提交 hash、
|
||||
CI 运行链接、执行人(人或宿主操作,不是你自己合);
|
||||
合并后删远程分支,删前确认合并提交已在主线。
|
||||
- 发布与回滚:按端打 tag,例如 v0.1.0,发布说明从已合 PR 汇总;
|
||||
回滚是 revert 对应 PR 或重部署上一个 tag,绝不是 force-push 回退。
|
||||
- 安全:密钥、口令、token 绝不进代码、commit、命令行、PR 正文、日志;
|
||||
token 只进子进程环境(cloud/pr.py 的做法:只进子进程环境变量 GIT_TOKEN,
|
||||
不进命令行参数、不进远端 URL);新仓库首 commit 前检查 .gitignore
|
||||
覆盖密钥文件与本地配置文件。
|
||||
|
||||
## 附录角色:01-product-manager(来源 templates/roles/01-product-manager.md)
|
||||
|
||||
# 角色模板:产品经理(1 个线程)
|
||||
@@ -542,6 +646,19 @@ tests/ # QA 线程专属,含跨端一致性用例
|
||||
|
||||
---
|
||||
|
||||
|
||||
## GitHub 交付(客户端)
|
||||
|
||||
- 你的工作只在自己的分支上做,分支名由协调员给定,
|
||||
格式 feat/swe/<阶段>-<角色>-<简称>;绝不直接推默认分支,
|
||||
绝不对默认分支 force-push;落后主线先按协调员写清的方式同步主线再提 PR。
|
||||
- 交付必须含 PR 号:推分支、建 PR,正文写清范围(你的拥有目录)、
|
||||
契约版本、测试证据、已知问题、关联待办或 PRD 项。没有 PR 号不算完成。
|
||||
- 合并门由协调员判定:Checks 全绿、目录归属通过、契约版本是冻结版、
|
||||
评审通过且无未解决意见;你不自己合并、不绕过评审推主线。
|
||||
- 安全:密钥、口令、token 绝不进代码、commit、命令行、PR 正文;
|
||||
需要调用 GitHub 时 token 只进子进程环境,不写进示例命令。
|
||||
|
||||
## 附录角色:05-backend(来源 templates/roles/05-backend.md)
|
||||
|
||||
# 角色模板:后端 / API(可选,1 个线程)
|
||||
@@ -651,6 +768,16 @@ iOS / Android / Mac 在 Linux 主机上编不出来时,你的结论写
|
||||
|
||||
---
|
||||
|
||||
|
||||
## 按端发布与回滚(验收)
|
||||
|
||||
- 发布按端分别做:每端发布时打 tag,例如 v0.1.0;
|
||||
发布说明从已合 PR 汇总,不凭记忆重写;发布记录里写清端、tag、PR 号、执行人。
|
||||
- 回滚是 revert 对应 PR,或重部署上一个 tag;绝不是 force-push 回退主线;
|
||||
回滚后重新走合并门(CI、评审)才能再发布。
|
||||
- 合并记录复核:PR 号、合并提交 hash、CI 运行链接、执行人缺一项,
|
||||
验收就不算完成;已删远程分支的要确认合并提交已在主线。
|
||||
|
||||
## 附录角色:08-shared-core(来源 templates/roles/08-shared-core.md)
|
||||
|
||||
# 角色模板:共享核心(G3,1 个线程)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
"""software-engineering 技能的 GitHub 保证:轻量关键词断言。
|
||||
|
||||
只断言正文与附录都含有 GitHub 保证的关键概念,不逐字背诵全文:
|
||||
主分支保护、merge commit、revert 回滚、PR 号要求、force-push 禁止、
|
||||
tag 发布、token 只进子进程环境。附录是播种随附版,正文改了附录
|
||||
没同步时,本测试在附录部分就会失败。
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
SKILL = Path(__file__).resolve().parents[1] / "skills" / "software-engineering" / "SKILL.md"
|
||||
|
||||
KEYWORDS = ("主分支保护", "merge commit", "revert", "PR 号",
|
||||
"force-push", "tag", "子进程环境",
|
||||
"GET /tasks/{id}/pr/checks")
|
||||
|
||||
|
||||
class SoftwareEngineeringGithubTestCase(unittest.TestCase):
|
||||
def test_github_guarantees_in_body_and_appendix(self):
|
||||
text = SKILL.read_text(encoding="utf-8")
|
||||
main, sep, appendix = text.partition("## 附录:角色模板")
|
||||
self.assertTrue(sep, "appendix marker missing")
|
||||
for kw in KEYWORDS:
|
||||
self.assertIn(kw, main, kw)
|
||||
self.assertIn(kw, appendix, "appendix: " + kw)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user