diff --git a/cloud/skills/software-engineering/SKILL.md b/cloud/skills/software-engineering/SKILL.md index fc803c7..2023a13 100644 --- a/cloud/skills/software-engineering/SKILL.md +++ b/cloud/skills/software-engineering/SKILL.md @@ -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 个线程) diff --git a/cloud/tests/test_software_engineering_github.py b/cloud/tests/test_software_engineering_github.py new file mode 100644 index 0000000..ce07dd4 --- /dev/null +++ b/cloud/tests/test_software_engineering_github.py @@ -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()