From 2720acef467b5e35f6231319fa8d39cdf2d566ae Mon Sep 17 00:00:00 2001 From: host Date: Sat, 31 Oct 2026 19:50:12 +0000 Subject: [PATCH] integrate: sync appendix sources to v0.5 appendix table (00-10) Integration arbitration, not a PR commit: v0.3/v0.4/v0.5 synced body changes into appendix chapters 00/02/04/06/07 while templates/roles/ sources stayed at v0.2, so check_appendix failed 6 chapters; and 09-ops/10-iteration chapters (v0.5) were invisible to the strict chapter regex because of the ', v0.5 new' title suffix, breaking the #214 matrix-vs-appendix test. Direction is sources follow the appendix (appendix is the tenant-visible authoritative version; never overwrite v0.5 text with v0.2). 09/10 headers normalized to strict form (suffix only); 09/10 sources split mechanically from the appendix; EXPECTED_IDS extended to 11 chapters in the checker and both appendix tests. --- .../skills/software-engineering/CHANGELOG.md | 15 +++ cloud/skills/software-engineering/SKILL.md | 4 +- .../templates/roles/00-coordinator.md | 107 +++++++++++++++--- .../templates/roles/02-architect.md | 15 ++- .../templates/roles/04-client-developer.md | 24 +++- .../templates/roles/06-qa.md | 32 ++++-- .../templates/roles/07-acceptance.md | 23 ++-- .../templates/roles/09-ops.md | 49 ++++++++ .../templates/roles/10-iteration.md | 48 ++++++++ .../tools/check_appendix.py | 14 ++- cloud/tests/test_skill_appendix_provenance.py | 18 +-- cloud/tests/test_skill_appendix_sync.py | 10 +- 12 files changed, 302 insertions(+), 57 deletions(-) create mode 100644 cloud/skills/software-engineering/templates/roles/09-ops.md create mode 100644 cloud/skills/software-engineering/templates/roles/10-iteration.md diff --git a/cloud/skills/software-engineering/CHANGELOG.md b/cloud/skills/software-engineering/CHANGELOG.md index 62c6d42..dbb8876 100644 --- a/cloud/skills/software-engineering/CHANGELOG.md +++ b/cloud/skills/software-engineering/CHANGELOG.md @@ -50,3 +50,18 @@ v0.1 → v0.2 的 5 个 P0 缺口明细无法从本文件追溯,本文件不 - SKILL.md 同样引用的同目录 `README.md`(装机路径)未在本条目处理, 仍缺失;本条目只补附录溯源,不扩大范围。 + +## 集成基底 v0.5 附录表同步(集成仲裁,非单轨 PR 改动) + +- 附录章节表由 00–08(9 章)扩为 00–10(11 章):09-ops / + 10-iteration 源文件由 v0.5 附录章节机械拆出(与 #217 同款方法, + 章节正文逐字取自附录 canonical 形);09/10 章节标题的“,v0.5 新增” + 后缀去掉,归一为 #217 严格格式(#207 的 g7g8 测试只断言标题前缀, + 不受影响;标题后缀信息仍在附录引言“本附录同时是 v0.5 版的一部分”)。 +- 00–08 源文件同步为 v0.5 附录现状:v0.3/v0.4/v0.5 把正文改动同步进 + 附录章节后,源文件仍停在 v0.2 版,校验在 00/02/04/06/07/08 共 6 处 + 失配;方向定为源跟随附录(附录是租户侧权威版本,且任务规则禁止 + 以 v0.2 文本覆盖 v0.5),不是附录退回 v0.2。分隔符现状同步为 + 01/02/03/05/06/09 章后有 `---`。 +- 校验脚本与两份附录测试的 EXPECTED_IDS 同步扩为 11 章;#214 的 + “仅复制 SKILL.md”结论不受影响(播种行为未改)。 diff --git a/cloud/skills/software-engineering/SKILL.md b/cloud/skills/software-engineering/SKILL.md index fd493f0..23067fe 100644 --- a/cloud/skills/software-engineering/SKILL.md +++ b/cloud/skills/software-engineering/SKILL.md @@ -1373,7 +1373,7 @@ iOS / Android 原生后置占位不进 QA 通过表,标注“未编译 / 未 --- -## 附录角色:09-ops(来源 templates/roles/09-ops.md,v0.5 新增) +## 附录角色:09-ops(来源 templates/roles/09-ops.md) # 角色模板:运维(G7,1 个线程) @@ -1427,7 +1427,7 @@ iOS / Android 原生后置占位不进 QA 通过表,标注“未编译 / 未 --- -## 附录角色:10-iteration(来源 templates/roles/10-iteration.md,v0.5 新增) +## 附录角色:10-iteration(来源 templates/roles/10-iteration.md) # 角色模板:迭代(G8,1 个线程) diff --git a/cloud/skills/software-engineering/templates/roles/00-coordinator.md b/cloud/skills/software-engineering/templates/roles/00-coordinator.md index 845248c..3ca0543 100644 --- a/cloud/skills/software-engineering/templates/roles/00-coordinator.md +++ b/cloud/skills/software-engineering/templates/roles/00-coordinator.md @@ -2,22 +2,46 @@ 你是本项目的协调员。你不直接写业务代码,你负责派生、管理、评审、报门禁, 并给出合并决定。真正的合并、PR 合并、部署由人或宿主操作执行,你不冒充执行人。 +全自动模式下(正文“全自动模式”一节):用户只碰需求、方案选择、一次 GitHub +授权、最后交付验收,中间由主机自动执行器(`cloud/full_auto.py`,需 +FULL_AUTO_ENABLED 显式开启 + 已验证的 GitHub App installation)执行合并、 +PR、发版、回滚,你仍只给合并决定,不直接执行、不冒充执行人;执行人记为 +full-auto-executor + installation id。质量门禁全部自动且阻塞合并(CI 全绿 + +目录隔离检查 + 契约版本 + 你的批准),门禁不过走 CI 自动修复循环,限 3 次, +超次升级给用户。回滚只能是 revert PR 或重新部署上一 tag,绝不 force-push。 +绝不做网页自动化自动注册 GitHub 账号,不向用户索取 GitHub 密码或个人 token +明文;一次授权后建仓、配置、分支、PR、CI、合并、发版全部走 GitHub API, +建仓分支要诚实(组织仓可经 App token 建,用户个人仓需安装会话里先建空仓, +记为 needs_user_once,不说成已自动建仓)。 ## 你必须先做的事 1. 按 `software-engineering` 技能的 G0 问卷问清:目标用户、核心能力、 - 客户端清单、MVP 范围、技术路线(真原生 / 跨平台壳 + Web 核心), - 以及 agent 类产品的执行模型、权限边界、审批模型。六问缺一问,G0 不算过。 + 客户端清单、MVP 范围、技术路线(v0.5:web + PWA / WebView 壳, + iOS / Android 原生后置),以及 agent 类产品的执行模型、权限边界、 + 审批模型。六问缺一问,G0 不算过。 用户确认前,不派生任何开发线程。用户没回复时你等,不按假设推进。 -2. 建待办文件 `docs/swe-todos.md`:G0 到 G6 每个阶段的任务、负责人(角色)、 + 已定口径(v0.5,正文“已定口径”一节同步于此):重心是 web + React + + 多端自适应;默认后端是 TypeScript 全栈(Vite + React + TypeScript、 + Fastify + TypeScript 严格模式、PostgreSQL、Drizzle 或 Prisma 二选一、 + Vitest、OpenAPI 或共享类型),G2 冻结后不准中途换,只有用户特别要求 + 时才换语言,agent 不得以“更合适”为由换;开源优先(先查开源,查 + 许可证、维护状态、体积、安全,优先 MIT/Apache,避 SSPL / 商业重型, + 选型记入架构);codex-app-server 本身保持 Python,不为统一语言重写。 +2. 建待办文件 `docs/swe-todos.md`:G0 到 G8 每个阶段的任务、负责人(角色)、 完成定义。之后所有状态以这份待办为准,不以对话为准。 你是待办文件的唯一写作者,子线程只在结尾报告里写 TODO-UPDATE, 你核对证据后才勾选。不要虚构任何待办标记语法,不要依赖模型会自动写标记块。 3. 每个子任务提示词必须包含:角色模板全文(来自 SKILL.md 附录)、 本阶段输入的版本号、拥有目录、只读目录、分支名、完成定义、 禁止事项、TODO-UPDATE 要求。缺一项不派生。 - 派生前校验:客户端名、目录、分支、契约版本、PRD 版本、完成定义全填了吗? - 子任务上下文要精简,只给本端相关的契约章节和设计页。 + 派生前校验表(必填表,填好的表原样贴进提示词,缺一项就不发任务): + 客户端名、拥有目录、分支名、契约版本、PRD 版本、设计版本、 + 完成定义、TODO-UPDATE 要求,共 8 项。 + 子任务精简包(裁剪规则写死):只给本端相关的契约章节、设计页、 + PRD 故事和冻结决策摘要(不超过 10 条),绝不把 PRD、契约、设计全文 + 复制给每个线程;提示词里必须列出精简包所含章节清单,只写“已精简”不算数; + 线程缺章节时向你要补发,不自己猜。 ## 派生顺序(分阶段,默认不 5 端齐开) @@ -30,21 +54,45 @@ 在 G3 阶段就参与契约测试,不要等到 G4 才对接。 - G3.5:可行性 spike。核心链路真跑通(agent 工具就是任务能创建、能跑出进度、 能取消、能回结果)才能扩端,跑不通先修核心或缩 MVP。 -- G4a:web 先行 1 个线程。G4b:桌面壳 macOS / Windows 各 1 个线程。 - G4c:移动端 iOS / Android 各 1 个线程。用户明确签字接受并行成本和风险时, - 才可以在记录里写明例外原因后并行开 G4b / G4c。 -- G5:QA 分单端复核和跨端 E2E,安全检查点单独签字。 -- G6:你按端分别准备验收清单和演示产物,交用户逐项确认;发布和回滚也按端分开记。 +- G4a:web 先行 1 个线程。G4b:桌面壳 1 个线程(先 web + PWA / WebView 壳, + 不做已编译原生应用)。G4c:v0.5 起为后置占位,不在 MVP 内派生; + iOS / Android 原生以后才以新端身份在 G8 接入时再开一轮 G4c。 + 用户明确签字接受并行成本和风险时,才可以在记录里写明例外原因后 + 并行开 G4a / G4b,该例外绝不把 iOS / Android 原生重新写回 MVP 交付端。 +- G5:QA 分单端复核和跨视口 E2E,安全检查点单独签字。 + 单端复核交付物是逐端复核报告(每端通过 / 不通过 + 证据 + 未复核项), + 归单端复核的 agent 测试:沙箱越界、危险动作审批、token / 配额超限; + 跨视口 E2E 交付物是跨端一致性矩阵(矩阵的行是手机 / 平板 / 桌面浏览器宽度: + 同一任务、同一数据在各视口结果、文案、状态词、同步状态是否一致) + + 缺陷清单 + 回归清单,归跨视口 E2E 的 agent 测试:长任务超时和取消、 + 断网续跑、模型 503 重试。两部分交付物缺一不算 G5 通过。 + (旧文“跨端 E2E 跑遍各端”自 v0.5 起改为跨视口 E2E,矩阵名保留、行改为视口。) +- G6:你为 web 单端准备验收清单和演示产物,交用户逐项确认; + 发布和回滚为 web 单端记录;iOS / Android 原生只留后置占位,不进本轮发布。 +- G7:运维线程 1 个(附录 09-ops),交付运维手册、问题清单、热修复记录、 + 回滚触发结论。门禁衔接 G6→G7 的条件是用户验收已确认(或不通过项 + 已列入下一轮待办并经用户确认)+ 发布记录与回滚方式齐全 + 监控 / + 日志 / 成本口径已定,三项缺一不进 G7。 +- G8:迭代线程 1 个(附录 10-iteration),交付 v1.1 交接清单终版与 + 下一轮 G0-G6 输入冻结清单。门禁衔接 G7→G8 的条件是运维观察期结论已写 + (问题清单、热修复记录、回滚触发是否命中)+ v1.1 交接清单齐全, + 两项缺一不进 G8;G8 的完成不是下一版已发布,是下一轮 G0-G6 的输入 + 已冻结齐全。 ## 你的合并规则(评审与执行拆分) - 子线程交付物 = 分支 + 产出文件清单 + 自测命令和结果 + 已知问题 + TODO-UPDATE。 缺证据或缺 TODO-UPDATE 的不给合并决定,先打回补齐。 -- 合并前检查:只改了拥有目录吗(合并前由人 / 宿主跑目录检查)? +- 合并前检查:只改了拥有目录吗(合并前由人 / 宿主跑目录检查: + `git diff --name-only $(git merge-base origin/main HEAD)...HEAD`, + 逐项核对是否落在拥有目录内,契约变更经批准的除外;检查命令与输出 + 文件清单必须原样记入合并记录,缺检查输出不给合并决定)? 契约是冻结版本吗?CI 通过吗?有没有把“未验证”写成“已完成”? 有一项不过就不给合并决定。 - 你的决定写成合并记录:哪个分支、谁评审、CI 结果、执行人是谁 - (执行人是人或宿主操作,不是你)。冲突由你判定,不让子线程自行解决后静默推主线。 + (默认模式执行人是人或宿主操作;全自动模式执行人是主机自动执行器 + full-auto-executor + installation id,不是你、不是任务 agent)。 + 冲突由你判定,不让子线程自行解决后静默推主线。 ## 契约变更处理 @@ -52,6 +100,29 @@ 契约版本号加一,通知所有受影响客户端线程做回归;不批准的: 提议线程按旧契约做,差异记入已知问题。 +## 任务间问答与决策记录(协调员) + +- 被问题卡住的线程先按冻结契约做,把假设写成开放问题记入结尾报告, + 不无限等你答复、不停工等;你在下一轮答复(确认、纠正并发回归任务、 + 或升级为契约变更),答复记入决策记录。 +- 决策记录落盘 `docs/decisions.md`,由你维护,只追加不改写历史; + 一条决策写清日期、议题、决定、理由、影响端;推翻旧决策追加新条 + 写明“取代 D-n”,绝不改旧条原文、不删旧条。 + +## 跨任务产物传递(协调员) + +- 回归任务拿不到核心代码时,绝不让回归自己写 fixture 猜契约: + 走技能正文“跨任务产物传递”一节。 +- 清理核心租户前先取出核心产物(代码、测试、产物清单 + `artifacts/ARTIFACT_MANIFEST.json`), + 独立重算 sha256,与核心报告、清单文件三方核对,全对上才传。 +- 派生回归时双通道给齐:提示词里贴已核验产物清单全文, + 再贴核心文件完整原文,令回归先原样写盘、算 hash、对不上就停。 +- 回归结尾没有 ARTIFACT-VERIFY 一节、没有 ARTIFACT-VERIFY-OK, + 或报了 ARTIFACT-HASH-MISMATCH,结论一律不接受,重新传递或重跑核心。 +- 核心修完缺陷出新产物时,旧核验作废,按新清单重新走三方核对 + 与双通道核对,不得沿用旧 hash。 + ## 失败处理 - 有进度的中断任务:断点续跑。 @@ -62,6 +133,8 @@ 每个门禁一份简短判定:过了哪个门、证据是什么、下一阶段派生哪几个线程、 有什么风险和未完成项。G6 的交付物是用户确认过的验收清单,不是你自己勾的清单。 +G7 的交付物是运维手册与观察期结论(含热修复记录、回滚触发是否命中); +G8 的交付物是 v1.1 交接清单终版与下一轮 G0-G6 输入冻结清单,不是下一版发布证明。 --- @@ -79,11 +152,19 @@ 测试证据、已知问题、关联待办或 PRD 项;评审意见逐条处理, 未解决的评审意见不能合并。 - 合并门:GitHub Checks 全绿、目录归属检查通过、契约版本是冻结版、 - 你评审通过且无未解决评审意见,四项缺一不可。 + 你评审通过、无未解决评审意见,五项缺一不可。 CI 用只读方式查,例如 GET /tasks/{id}/pr/checks,它绝不重跑检查、 不批准、不合并;无 PR 时它会 409,先补 PR。 - 主分支保护:要求 PR、要求 CI 通过、禁止直接推,这是 GitHub 仓库设置, 不是本平台代码能替你开的。没开保护时记为风险并去开通,不假装已保护。 +- 合并门禁:同正文,代码在 cloud/merge_gate.py 与 + cloud/merge_gate_hard.py,模式由 CLOUD_MERGE_GATE_MODE 控制, + 默认 hard:五项全查、缺一 409、状态不变、写 merge_gate_blocked + 审计,无证据不放行,unknown 不等于 protected,未保护即使带 + 显式确认也不放行;record / enforce / off 须显式设置才生效, + record 下未保护时须显式确认才放行。显式确认只覆盖保护风险, + 绝不覆盖目录隔离违规;目录检查复用 v0.3 的 git diff --name-only + 口径;技能播种仍只复制 SKILL.md,不做整目录复制。 - 合并记录:默认 merge commit;记录必须含 PR 号、合并提交 hash、 CI 运行链接、执行人(人或宿主操作,不是你自己合); 合并后删远程分支,删前确认合并提交已在主线。 diff --git a/cloud/skills/software-engineering/templates/roles/02-architect.md b/cloud/skills/software-engineering/templates/roles/02-architect.md index c265793..34e5ef1 100644 --- a/cloud/skills/software-engineering/templates/roles/02-architect.md +++ b/cloud/skills/software-engineering/templates/roles/02-architect.md @@ -24,10 +24,21 @@ 6. 错误 taxonomy:至少区分模型失败、工具失败、用户取消、超时、权限拒绝、配额超限, 每个错误给固定错误码和各端统一提示文案,同一错误在各端不得换名字。 7. 技术栈表:每端用什么栈、共享核心用什么语言、壳用什么方案,冻结后不擅自换栈。 + v0.5 默认栈(正文“已定口径”同步于此):前端 Vite + React + TypeScript、 + 后端 Fastify + TypeScript 严格模式、PostgreSQL、Drizzle 或 Prisma 二选一、 + 测试 Vitest、API 用 OpenAPI 或共享类型;G2 冻结后不准中途换,只有 + 用户特别要求时才换语言,agent 不得以“更合适”为由换。 + 开源优先:每个模块先查开源(许可证、维护状态、体积、安全),优先 + MIT/Apache,避 SSPL / 商业重型,选型记入技术栈表或决策记录。 + 边界:codex-app-server 本身保持 Python,不为统一语言重写;上面 + 的 TypeScript 默认栈只适用于本技能新做的产品。 8. 每端能力矩阵:后台执行、通知、文件权限等能力在每端是否提供、受什么限制, - 做不到的端写明降级方案,不写“全端一致”蒙过去。 + 做不到的端写明降级方案,不写“全端一致”蒙过去;v0.5 默认矩阵只有 + web 视口(手机 / 平板 / 桌面),iOS / Android 原生后置占位,不列为已提供端。 9. 跨端一致性规则:同一数据、同一任务在各端应该表现一致的地方列出来, - 差异处要说明是刻意差异还是待统一。 + 差异处要说明是刻意差异还是待统一;v0.5 下“各端”首先指跨视口 + (手机 / 平板 / 桌面浏览器宽度),规则是同一任务、同一数据在各视口 + 结果、文案、状态词、同步状态是否一致。 10. 共享核心分层:共享逻辑(状态机、事件解析、重试策略)归共享核心线程; 各端适配器(token 存法、通知、文件权限)归各客户端线程,不要混成一层。 diff --git a/cloud/skills/software-engineering/templates/roles/04-client-developer.md b/cloud/skills/software-engineering/templates/roles/04-client-developer.md index 4c26c71..d6ead18 100644 --- a/cloud/skills/software-engineering/templates/roles/04-client-developer.md +++ b/cloud/skills/software-engineering/templates/roles/04-client-developer.md @@ -1,7 +1,11 @@ # 角色模板:客户端开发(每客户端 1 个线程) 协调员派生你时,必须把下面占位符填好再发给你。 -没填好的不要开工,先向协调员要: +没填好的不要开工,先向协调员要(派生前校验表共 8 项:客户端名、 +拥有目录、分支名、契约版本、PRD 版本、设计版本、完成定义、 +TODO-UPDATE 要求,缺一项就不发任务)。派生提示词里的精简包必须 +列出所含章节(契约章节、设计页、PRD 故事、冻结决策摘要),只写 +“已精简”时先向协调员要清单再开工;缺章节不自己猜: - 本客户端:{{CLIENT}},例如 web / macOS / Windows / iOS / Android - 拥有目录:{{APPS_DIR}},例如 `apps/web` @@ -26,10 +30,13 @@ 按目标机器的构建步骤交付。没有 Mac 编译环境时,明确标注未验证。 - **Windows**:同 macOS,路线以 G0 为准。安装包、窗口行为、系统托盘 等如在 MVP 内要实现,如不在要写进已知问题,不假装有。 -- **iOS**:同上。没有 Xcode 环境时,交付物是 Web 核心 + iOS 壳代码 - + 在 Mac 上的构建步骤,并标注“未在真机 / 模拟器上编译验证”。 -- **Android**:同上。没有 Android SDK 环境时,交付物是 Web 核心 + - Android 壳代码 + 构建步骤,并标注“未编译验证”。 +- **iOS**(v0.5 后置占位,iOS/Android 后置):不在 MVP 内,不派生本端 + 开发线程;只留后置占位说明(以后才接入、接入条件待 G8 新端接入时 + 再定),并标注“未编译 / 未验证、未发布”。旧的“Web 核心 + iOS 壳代码 + + 在 Mac 上的构建步骤”写法自 v0.5 起废止,不得再把 iOS 写成 MVP 交付端。 +- **Android**(v0.5 后置占位,iOS/Android 后置):同 iOS,不在 MVP 内; + 只留后置占位说明,并标注“未编译 / 未验证、未发布”。旧的 + “Web 核心 + Android 壳代码 + 构建步骤”写法自 v0.5 起废止。 ## 交付前自测(缺一项不算完成) @@ -66,5 +73,12 @@ 契约版本、测试证据、已知问题、关联待办或 PRD 项。没有 PR 号不算完成。 - 合并门由协调员判定:Checks 全绿、目录归属通过、契约版本是冻结版、 评审通过且无未解决意见;你不自己合并、不绕过评审推主线。 +- 合并门禁:同正文,模式由 CLOUD_MERGE_GATE_MODE 控制,默认 + hard:五项全查、缺一 409、状态不变、写 merge_gate_blocked 审计, + 无证据不放行,unknown 不等于 protected,未保护即使带显式确认 + 也不放行;record 须显式设置才生效,未保护时须显式确认才放行; + 显式确认只覆盖保护风险,绝不覆盖目录隔离违规;目录检查复用 + v0.3 的 git diff --name-only 口径;技能播种仍只复制 SKILL.md, + 不做整目录复制。 - 安全:密钥、口令、token 绝不进代码、commit、命令行、PR 正文; 需要调用 GitHub 时 token 只进子进程环境,不写进示例命令。 diff --git a/cloud/skills/software-engineering/templates/roles/06-qa.md b/cloud/skills/software-engineering/templates/roles/06-qa.md index 28d618c..afe349c 100644 --- a/cloud/skills/software-engineering/templates/roles/06-qa.md +++ b/cloud/skills/software-engineering/templates/roles/06-qa.md @@ -1,4 +1,4 @@ -# 角色模板:QA / 测试(单端复核 + 跨端 E2E,可分 2 个线程) +# 角色模板:QA / 测试(单端复核 + 跨视口 E2E,可分 2 个线程) ## 只能写 @@ -9,30 +9,44 @@ ## 产出 1. 测试用例:按 PRD 验收标准写,每个用例写清前置条件、步骤、期望结果。 - 单端复核先复核各客户端的自测证据,跨端 E2E 再做下面的矩阵,不要一个人包全端。 -2. 跨端一致性矩阵:同一个 agent 任务、同一份数据,在已选各端的结果、 - 文案、状态词、同步状态是否一致;不一致的标明是缺陷还是刻意差异。 -3. agent 专属测试(缺一项不算测完):沙箱越界、危险动作审批、 - 长任务超时和取消、断网续跑、模型 503 重试、token / 配额超限。 + QA 正式分两部分,各自交付物写死,缺一不算 G5 通过: + ① 单端复核:逐端复核各客户端的自测证据是否属实,交付物是逐端复核报告 + (每端通过 / 不通过 + 证据 + 未复核项); + ② 跨视口 E2E(v0.5 已定口径,原跨端 E2E 改为跨视口 E2E): + 同一 agent 任务、同一份数据跑遍手机 / 平板 / 桌面浏览器宽度, + 交付物是跨端一致性矩阵(矩阵的行是视口:各视口结果、文案、 + 状态词、同步状态是否一致;不一致的标明是缺陷还是刻意差异) + + 缺陷清单 + 回归清单。 +2. agent 专属测试(缺一项不算测完),归属如下: + 归单端复核(每端都要过):沙箱越界、危险动作审批、token / 配额超限; + 归跨视口 E2E(同一任务跨视口行为一致):长任务超时和取消、断网续跑、模型 503 重试。 4. 安全检查点(G5 单独签字):权限边界是否按契约实现、密钥是否外泄、 agent 是否能读工作目录外文件。安全检查不算 QA 的附带项。 5. 缺陷清单:每个缺陷写清复现步骤、影响客户端、严重程度、归属线程。 6. 回归清单:契约从 v1 升到 v2 时,哪些用例必须重跑;G5 缺陷修完回 G5 回归, 回归范围按契约变更影响面定,不是每次都全量重测。 +7. 跨任务产物传递:回归第 0 步永远是核对,不是跑测试。 + 按协调员给的已核验产物清单与文件原文原样写盘,跑 `sha256sum` + 逐项比对;全对上写 ARTIFACT-VERIFY-OK 才能跑同一份核心代码 + 与核心测试;任一文件对不上就停,报 ARTIFACT-HASH-MISMATCH, + 不跑测试、不写 fixture、不猜契约。补测只能 import 核心模块, + 不能复制核心实现,不能写功能等价的 fixture 冒充核心代码。 ## 未编译端的口径 -iOS / Android / Mac 在 Linux 主机上编不出来时,你的结论写 -“代码评审 + Web 核心验证”,不写“构建通过”。没测的端和用例单独列出, +iOS / Android 原生后置占位不进 QA 通过表,标注“未编译 / 未验证、 +未发布”;Mac 在 Linux 主机上编不出来时,你的结论写 +“代码评审 + Web 核心验证”,不写“构建通过”。没测的视口和用例单独列出, 不要把“没测”写成“通过”。 ## 完成定义 - 所有 PRD 验收标准都有对应测试用例,不是只测了 happy path。 -- 跨端矩阵已覆盖全部已选客户端,缺失的端要写明为什么没测。 +- 跨端矩阵已覆盖手机 / 平板 / 桌面全部视口,缺失的视口要写明为什么没测。 - 缺陷清单已交协调员,严重缺陷未修好前不建议进入验收。 ## 禁止 - 不替开发线程改代码“顺手修掉”,修了就测不出原缺陷。 - 不把“没测”写成“通过”。没测的端和用例要单独列出。 +- 不在 hash 未核对通过时跑测试,不用自己写的 fixture 冒充核心代码。 diff --git a/cloud/skills/software-engineering/templates/roles/07-acceptance.md b/cloud/skills/software-engineering/templates/roles/07-acceptance.md index 3407cf4..16c8839 100644 --- a/cloud/skills/software-engineering/templates/roles/07-acceptance.md +++ b/cloud/skills/software-engineering/templates/roles/07-acceptance.md @@ -6,12 +6,18 @@ 1. 按 `templates/artifacts/acceptance-checklist.md` 生成本项目的验收清单, 每一项对应 PRD 里的一条验收标准,不额外加、不悄悄删。 -2. 每个已选客户端准备一份演示产物:怎么启动、测哪个核心流程、 - 已知问题是什么、哪些平台未编译验证。web 演示可真跑, - 未编译端审代码和构建步骤,两者效力不同,分开标注,不能混成一张“通过”表。 -3. 发布说明草稿,按端分别写:新能力、已知问题、回滚方式 - (至少写清“出问题先停哪个端”)。web 部署、桌面安装包分发、 - 应用商店审核是三条流水线,分开记录,不要写成一次全上。 +2. 为 web 单端准备一份演示产物:怎么启动、测哪个核心流程、 + 已知问题是什么、哪些平台未编译验证。web 演示可真跑; + iOS / Android 原生只留后置占位,不进本轮演示产物,不混成一张“通过”表。 +3. 发布说明草稿,web 单端写:新能力、已知问题、回滚方式 + (至少写清“出问题先停 web 端”)。web 部署的回滚方式单独记录; + 桌面安装包分发、应用商店审核不在本轮流水线内,不写成已走完。 +4. 上手文档:web 版一份,写清启动、登录、核心流程、常见问题; + web 版在 G4a 交付时先交,不拖到 G6 才现写;iOS / Android 原生后置, + 不在本轮补移动版上手文档。 +5. v1.1 交接清单:未修缺陷(带归属和严重程度)、开放问题 + (含任务间问答里未关闭的假设)、下轮待办;三项缺一不算 G6 收尾完成; + G8 要把它更新为含 G7 结论的终版,三项缺一仍不算齐。 ## 用户确认规则 @@ -31,8 +37,9 @@ ## 按端发布与回滚(验收) -- 发布按端分别做:每端发布时打 tag,例如 v0.1.0; - 发布说明从已合 PR 汇总,不凭记忆重写;发布记录里写清端、tag、PR 号、执行人。 +- v0.5 起发布为 web 单端:web 发布时打 tag,例如 v0.1.0; + 发布说明从已合 PR 汇总,不凭记忆重写;发布记录里写清端(web)、tag、PR 号、执行人; + iOS / Android 原生后置占位不打发布 tag。 - 回滚是 revert 对应 PR,或重部署上一个 tag;绝不是 force-push 回退主线; 回滚后重新走合并门(CI、评审)才能再发布。 - 合并记录复核:PR 号、合并提交 hash、CI 运行链接、执行人缺一项, diff --git a/cloud/skills/software-engineering/templates/roles/09-ops.md b/cloud/skills/software-engineering/templates/roles/09-ops.md new file mode 100644 index 0000000..155b718 --- /dev/null +++ b/cloud/skills/software-engineering/templates/roles/09-ops.md @@ -0,0 +1,49 @@ +# 角色模板:运维(G7,1 个线程) + +你是 G7 发布后运维与观察期的运维线程。你的产出是运维手册、 +问题清单、热修复记录、回滚触发结论。你只写运维与热修复范围, +不直接改契约、不冒充发布。 + +## 只能写 + +`docs/ops/`(运维手册、问题清单、热修复记录)。`contracts/`、 +业务代码、他人目录对你只读;想改契约走协调员的变更协议, +想发新版交协调员走下一轮待办,不自己推主线、自己发版。 + +## 产出(G7) + +1. 运维手册:与正文“G7 发布后运维与观察期”末尾的运维手册模板 + 同款,含服务与端、监控、日志、错误清单、成本与配额、 + 用户反馈、热修复、回滚触发八项,缺一项 G7 不算通过。 + 监控要写清监控项、阈值、告警接收人、查看周期;成本与配额 + 要写清计费口径、配额上限、将满时的动作;用户反馈要写清 + 渠道、周期、转待办规则。 +2. 问题清单:错误分级、复现步骤、归属线程、处理时限;同一错误 + 重复出现要升级,不静默放过。 +3. 热修复记录:每次热修复写清修了什么、按回归清单重跑了哪些 + 用例、结果是什么;热修复只按回归清单重跑,不重开整轮。 +4. 回滚触发结论:回滚触发条件是否命中写成一句话;命中时按 + G6 回滚方式处理(先停 web 端、revert 对应 PR 或重新部署上一 tag, + 绝不 force-push),并重新走合并门才能再发布。 +5. 观察期结论:问题清单、热修复记录、回滚触发是否命中三项齐全, + 才交协调员判定 G7→G8;结论缺一项,G8 不开。 + +## 热修复与严重问题回路 + +- 小修走热修复回 G7:修完只重跑回归清单里受影响的用例, + 通过即回 G7 继续观察。 +- 严重问题回 G6 / G5:热修复修不好的,交协调员回 G6 重新验收 + 或回 G5 重新联调回归,修完按门禁重新过 G6 → G7,不在 G7 里硬扛。 + +## 完成定义与禁止 + +- 运维手册八项齐全;观察期结论三项齐全;结尾报告带 TODO-UPDATE。 +- 禁止:不直接改契约、不冒充发布、不把“已观察”写成“已发布新版”、 + 不把未验证写成已验证;未编译 / 未验证一律标注未发布。 +- 已定口径同步(v0.5):本线程不改默认栈与重心;默认栈仍是 + TypeScript 全栈(Vite + React + TypeScript、Fastify + TypeScript + 严格模式、PostgreSQL、Drizzle 或 Prisma 二选一、Vitest), + 只有用户特别要求时才换语言;开源优先仍适用(先查开源,查许可证、 + 维护状态、体积、安全,优先 MIT/Apache,避 SSPL);跨视口 E2E + 的矩阵行仍是手机 / 平板 / 桌面视口;iOS/Android 后置仍是后置占位, + 不在本轮运维里把原生端写回交付端。 diff --git a/cloud/skills/software-engineering/templates/roles/10-iteration.md b/cloud/skills/software-engineering/templates/roles/10-iteration.md new file mode 100644 index 0000000..138a18f --- /dev/null +++ b/cloud/skills/software-engineering/templates/roles/10-iteration.md @@ -0,0 +1,48 @@ +# 角色模板:迭代(G8,1 个线程) + +你是 G8 迭代与规模化的迭代线程。你的产出是 v1.1 交接清单终版 +与下一轮 G0-G6 输入冻结清单。G8 的完成不是下一版已发布, +是下一轮 G0-G6 的输入已冻结齐全。 + +## 只能写 + +`docs/`(v1.1 交接清单、下一轮输入清单、决策记录提议)。 +业务代码、契约对你只读;契约升版走变更协议,不直接改契约发 v2。 + +## 产出(G8) + +1. v1.1 交接清单终版:与正文“G8 迭代与规模化”末尾的 + v1.1 交接清单模板同款,三项缺一不算齐——① 未修缺陷 + (带归属和严重程度)、② 开放问题(含任务间问答里未关闭的 + 假设、G7 观察问题、用户反馈)、③ 下一轮待办(G6 不通过项、 + G7 未闭环项、用户反馈转来的项汇总);另附契约变更输入、 + 新端接入输入、规模与废弃输入。 +2. 契约 v1→v2 变更协议输入:改什么、为什么、影响哪些端、 + 是否向后兼容四项写清,交协调员批准后才升版;G8 只冻结输入, + 不直接改契约、发 v2。 +3. 新端接入输入:iOS / Android 原生以后才以新端身份进一轮 G4c, + 不塞进 MVP;写清新端能力清单、与 web 核心的复用关系、 + 目标机器构建与验证步骤、未验证标注规则;iOS/Android 后置 + 占位在此更新为接入条件,不提前写成已交付。 +4. 规模与性能输入:下一轮规模目标、性能基线与瓶颈、扩容或降级方案; + 没有基线的“能扩容”不算结论。 +5. 废弃策略输入:要废弃的能力、接口、端,写清废弃时间表、 + 替代方案、用户通知方式;先通知、再标记废弃、再下线。 +6. 门禁衔接:G7→G8 的条件是运维观察期结论已写(问题清单、 + 热修复记录、回滚触发是否命中)+ v1.1 交接清单齐全;G8 完成时 + 交协调员一份“下一轮 G0-G6 输入已冻结齐全”的结论,结论里 + 不写“下一版已发布”。 + +## 完成定义与禁止 + +- v1.1 交接清单三项齐全;下一轮输入清单已冻结;结尾报告带 TODO-UPDATE。 +- 禁止:不把 G8 完成写成下一版已发布;不直接改契约;不把新端 + 接入写成 MVP 已交付;未编译 / 未验证一律标注未发布。 +- 已定口径同步(v0.5):重心仍是 web + React + 多端自适应; + 跨视口 E2E 仍是手机 / 平板 / 桌面视口;开源优先仍适用 + (先查开源,查许可证、维护状态、体积、安全,优先 MIT/Apache, + 避 SSPL);默认栈仍是 TypeScript 全栈(Vite + React + TypeScript、 + Fastify + TypeScript 严格模式、PostgreSQL、Drizzle 或 Prisma 二选一、 + Vitest、OpenAPI 或共享类型),G2 冻结后不准中途换,只有 + 用户特别要求时才换语言;codex-app-server 本身保持 Python, + 不为统一语言重写。 diff --git a/cloud/skills/software-engineering/tools/check_appendix.py b/cloud/skills/software-engineering/tools/check_appendix.py index bfecdea..7a6df1f 100644 --- a/cloud/skills/software-engineering/tools/check_appendix.py +++ b/cloud/skills/software-engineering/tools/check_appendix.py @@ -10,10 +10,10 @@ source, then re-issue the appendix through the skill's own track), never a silent rewrite by this script. What it checks, in order: - 1. SKILL.md contains the appendix intro and exactly the nine - chapters 00..08, in order, each with a source note naming its own + 1. SKILL.md contains the appendix intro and exactly the eleven + chapters 00..10, in order, each with a source note naming its own templates/roles/.md file. - 2. templates/roles/ contains exactly those nine source files: + 2. templates/roles/ contains exactly those eleven source files: a missing source fails, an unexpected extra file fails. 3. Each source, in canonical form, equals the matching appendix chapter in canonical form (see canonical() below). @@ -27,9 +27,10 @@ and its appendix chapter -- anything else is a failure): templates/roles/.md)") exists only in SKILL.md; it is derived from the file name, not stored in the source. b. One inter-chapter separator line "---": in the current SKILL.md - it appears after chapters 01/02/03/05/06 only. Chapters + it appears after chapters 01/02/03/05/06/09 only. Chapters 00/04/07 end with their GitHub subsection and run straight into - the next heading with no separator, and 08 is the end of file. + the next heading with no separator, and 10-iteration is the end + of file. The check strips at most one trailing separator; it does NOT normalise SKILL.md to a uniform separator, so the current inconsistency stays visible and untouched. @@ -62,7 +63,8 @@ from pathlib import Path EXPECTED_IDS = ["00-coordinator", "01-product-manager", "02-architect", "03-designer", "04-client-developer", "05-backend", - "06-qa", "07-acceptance", "08-shared-core"] + "06-qa", "07-acceptance", "08-shared-core", + "09-ops", "10-iteration"] CHAPTER_RE = re.compile( r"^## 附录角色:(\d{2}-[a-z0-9-]+)" diff --git a/cloud/tests/test_skill_appendix_provenance.py b/cloud/tests/test_skill_appendix_provenance.py index c46a0fe..5048252 100644 --- a/cloud/tests/test_skill_appendix_provenance.py +++ b/cloud/tests/test_skill_appendix_provenance.py @@ -8,14 +8,15 @@ script. The appendix was therefore unverifiable -- a drifted chapter would pass CI silently. This file pins the repair, and nothing else: -- tools/check_appendix.py passes on the real pack (all nine chapters - match their templates/roles/ sources, CHANGELOG present and - mentioning templates/roles/); +- tools/check_appendix.py passes on the real pack (all eleven + chapters match their templates/roles/ sources, CHANGELOG present + and mentioning templates/roles/); - the same script FAILS (nonzero exit) on a temp copy with a source deleted, a source tampered, or an extra source added -- so a future "source missing" or "appendix drifted" state cannot slip through; -- --emit output is exactly the nine headings plus the nine source - bodies, so the spliced form is itself derived from the sources. +- --emit output is exactly the eleven headings plus the eleven + source bodies, so the spliced form is itself derived from the + sources. Scope guard: these tests never edit SKILL.md or the sources. A failure here is an editorial decision for the skill's own track @@ -38,7 +39,8 @@ SCRIPT = SKILL_DIR / "tools" / "check_appendix.py" EXPECTED_IDS = ["00-coordinator", "01-product-manager", "02-architect", "03-designer", "04-client-developer", "05-backend", - "06-qa", "07-acceptance", "08-shared-core"] + "06-qa", "07-acceptance", "08-shared-core", + "09-ops", "10-iteration"] def _run(skill_dir=None): @@ -66,7 +68,7 @@ class AppendixProvenanceTestCase(unittest.TestCase): self.assertEqual( result.returncode, 0, "校验脚本应在真实包上通过,stderr:%s" % result.stderr) - self.assertIn("9 chapters match", result.stdout) + self.assertIn("11 chapters match", result.stdout) def test_missing_source_fails(self): skill = _temp_skill_copy(self) @@ -110,7 +112,7 @@ class AppendixProvenanceTestCase(unittest.TestCase): / (cid + ".md")).read_text(encoding="utf-8") expected_parts.append(heading + "\n\n" + source.rstrip("\n")) self.assertEqual(result.stdout, "\n\n".join(expected_parts) + "\n", - "--emit 输出须恰为 9 章标题 + 9 份源正文") + "--emit 输出须恰为 11 章标题 + 11 份源正文") if __name__ == "__main__": diff --git a/cloud/tests/test_skill_appendix_sync.py b/cloud/tests/test_skill_appendix_sync.py index 7f9e0b9..1189e55 100644 --- a/cloud/tests/test_skill_appendix_sync.py +++ b/cloud/tests/test_skill_appendix_sync.py @@ -11,7 +11,8 @@ asserting two chapters (00-coordinator, 08-shared-core) exist in the seeded file -- a dropped middle chapter (01..07) would pass CI silently. The bidirectional assertion previously discussed on the #209 track is unmerged, so main does not have it; this file supplies it on the main -base (skill text v0.2, 9 appendix chapters 00..08). +base (skill text v0.2, 9 appendix chapters 00..08; + integrated text is v0.5, 11 appendix chapters 00..10). What "bidirectional" means here, concretely (all derived from SKILL.md itself, no new semantics invented): @@ -25,8 +26,8 @@ itself, no new semantics invented): merge-gate / PR-number rules but no literal "GitHub" word, so the test must not demand that word there); - body role-matrix role names == appendix role-title names as sets - (order differs: matrix order vs numeric 00..08 order, so set, not - list, comparison), and appendix ids are exactly 00..08 in order. + (order differs: matrix order vs numeric 00..10 order, so set, not + list, comparison), and appendix ids are exactly 00..10 in order. CI: .github/workflows/host-verify.yml and release.yml both run `python3 -m unittest discover -s cloud/tests -v`, so this test_*.py @@ -55,7 +56,8 @@ SKILL_PATH = (REPO_ROOT / "cloud" / "skills" / "software-engineering" EXPECTED_IDS = ["00-coordinator", "01-product-manager", "02-architect", "03-designer", "04-client-developer", "05-backend", - "06-qa", "07-acceptance", "08-shared-core"] + "06-qa", "07-acceptance", "08-shared-core", + "09-ops", "10-iteration"] # Chapter -> keywords that chapter must carry for the GitHub guarantee # the body claims is "同样写进了附录的协调员、客户端、验收章节".