From 44616a03dc80fd5df0e7fc55a0771ad7c64343a8 Mon Sep 17 00:00:00 2001 From: host Date: Fri, 30 Oct 2026 12:07:47 +0000 Subject: [PATCH] feat: software-engineering skill v0.5 (G7/G8 ops + iteration) Stacked on v0.3 + v0.4 (HEAD d6522ba feat-full-auto): v0.3/v0.4 content preserved, not reverted. Adds G7 post-release ops and observation (monitoring, errors, cost/quota, feedback, hotfix loop, rollback triggers, ops manual) and G8 iteration and scaling (v1.1 handover list, contract v1->v2 protocol, new-end onboarding, scale/performance, deprecation), with G6->G7 and G7->G8 gates, DAG, gate table, coordinator derivation, G0-G8 todos, checklist, 09-ops and 10-iteration role templates, and ops-manual / v1.1 handover templates in both body and appendix. Settles web+React+ multi-viewport focus, cross-viewport E2E, web single-end release with iOS/Android native postposed, open-source-first, and the TypeScript full-stack default (user-request-only language change; codex-app-server itself stays Python). Pending #199 and #205 merge, then one rebase round. PR only, do not merge or deploy. --- cloud/skills/software-engineering/SKILL.md | 481 +++++++++++++++--- cloud/tests/test_software_engineering_g7g8.py | 82 +++ 2 files changed, 489 insertions(+), 74 deletions(-) create mode 100644 cloud/tests/test_software_engineering_g7g8.py diff --git a/cloud/skills/software-engineering/SKILL.md b/cloud/skills/software-engineering/SKILL.md index ef9391b..5441894 100644 --- a/cloud/skills/software-engineering/SKILL.md +++ b/cloud/skills/software-engineering/SKILL.md @@ -1,10 +1,13 @@ --- name: software-engineering -description: 用户要从零做一款软件、尤其是要同时做 web、macOS、Windows、iOS、Android 多个客户端时使用。按产品规划、产品设计、架构契约、多客户端并行开发、联调测试、验收的顺序,用协调员任务派生角色线程推进,契约冻结后各客户端只在自己目录内开发,最后走评审合并与用户验收。只做单文件小改动、只问概念时不用本技能。 +description: 用户要从零做一款软件、首要交付 web(React、多视口自适应)时使用;iOS、Android 原生后置,不在 MVP 内。按产品规划、产品设计、架构契约、开发、联调测试、验收、运维、迭代的顺序,用协调员任务派生角色线程推进,契约冻结后各客户端只在自己目录内开发,最后走评审合并与用户验收。只做单文件小改动、只问概念时不用本技能。 --- # software-engineering:多客户端软件工程编排 +版本 v0.5,2026-10-30。上一版是 v0.4 全自动模式 + v0.3,v0.5 新增 +G7 发布后运维与观察期、G8 迭代与规模化,以及下面“已定口径”一节 +的重心与默认栈,v0.3 / v0.4 内容全部保留、不删改、不回退。 版本 v0.3,2026-10-30。上一版是 v0.2 + PR #193 GitHub 保证 (已合并、已部署生产)。v0.3 改了什么:P1-1 目录隔离自动化检查 (可执行命令 + 检查输出记入合并记录)、P1-2 派生占位符必填表 @@ -133,22 +136,38 @@ G0 接单选型 ──> G1 产品规划 ──> G2 产品设计 + 架构 ──> │ G4a web 先行 │ - G4b 桌面壳(macOS / Windows) + G4b 桌面壳(先 web + PWA / WebView 壳, + 不做已编译原生应用) │ - G4c 移动端(iOS / Android) - │ - G5 联调 + 跨端测试 + G5 联调 + 跨视口测试 ↑ │ └── 缺陷回 G4 修, 修完回 G5 回归 │ - G6 按端验收 + 按端发布 + G6 web 单端验收 + web 单端发布 + (iOS / Android 原生后置占位, + 不在 MVP 交付端内) + │ + G7 发布后运维与观察期 + ↑ │ + ├── 热修复回 G7(小修按回归清单重跑, + │ 不重开整轮) + └── 严重问题回 G6 / G5(见 G7 一节) + │ + G8 迭代与规模化 + │ + 下一轮 G0-G6 输入冻结 + (新端接入时再开一轮 G4c, + iOS / Android 原生以后才以新端身份进) ``` G4 分阶段不是“慢”,是止损:web 先行验证核心链路和契约, -桌面和移动复用已验证的契约和 Web 核心,返工面最小。 -用户明确签字“接受 5 端并行成本和风险”时,协调员可以在记录里写明 -例外原因后并行开 G4a / G4b / G4c,但默认不并行。 +桌面复用已验证的契约和 Web 核心,返工面最小。 +原 G4c 移动端(iOS / Android)自 v0.5 起改为后置占位:iOS / Android +原生明确后置,不在 MVP 链内、不作为 MVP 交付端,只在 G8 新端接入时 +再开一轮 G4c。用户明确签字“接受多端并行成本和风险”时,协调员可以 +在记录里写明例外原因后并行开 G4a / G4b,但默认不并行,且该例外 +绝不把 iOS / Android 原生重新写回 MVP 交付端。 ## 门禁表 @@ -162,9 +181,141 @@ G4 分阶段不是“慢”,是止损:web 先行验证核心链路和契约 | G3.5 | 可行性 spike 通过 | 核心链路在真实(或最接近真实的)环境里跑通:以 agent 工具为例,任务能创建、能跑出进度、能取消、能回结果;跑不通的原因已定位到模型、沙箱、后端三者之一 | 不进入 G4,先修核心链路或缩 MVP,不扩端摊成本 | | G4a | web 先行完成 | web 客户端满足角色模板的完成定义,有可运行产物或明确的未完成项 | 只重开 web 线程,不提前开桌面和移动 | | G4b | 桌面壳完成 | macOS / Windows 各满足完成定义,未编译项已标注验证步骤 | 只重开失败的那端 | -| G4c | 移动端完成 | iOS / Android 各满足完成定义,未编译项已标注验证步骤 | 只重开失败的那端 | -| G5 | 联调测试通过 | 单元、集成、跨端一致性、agent 安全测试、长任务测试、性能与安全检查都通过,失败项有归属和复现步骤;**安全检查点单独签字** | 回对应客户端或架构线程修,修完回 G5 回归,回归范围按契约变更影响面定 | -| G6 | 用户验收 | 用户按验收清单逐项确认,或明确列出不通过项;**验收和发布按端分别做**,web、桌面、移动的发布和回滚分开记录 | 不通过项变成新一轮待办,不算发布完成 | +| G4c | 移动端后置占位 | iOS / Android 原生明确后置(iOS/Android 后置),不在 MVP 内:只留占位说明与 G8 新端接入条件,不作为 MVP 交付端;未编译 / 未验证一律标注,不得写成已发布 | 不进 MVP 验收;待 G8 新端接入时再开一轮 G4c | +| G5 | 联调测试通过 | 单元、集成、跨视口一致性、agent 安全测试、长任务测试、性能与安全检查都通过,失败项有归属和复现步骤;**安全检查点单独签字**;跨视口 E2E 仍以跨端一致性矩阵为交付物,矩阵的行是手机 / 平板 / 桌面浏览器宽度(见“已定口径”) | 回对应客户端或架构线程修,修完回 G5 回归,回归范围按契约变更影响面定 | +| G6 | 用户验收(web 单端) | 用户按验收清单逐项确认,或明确列出不通过项;**验收和发布为 web 单端**,web 的发布和回滚分开记录,iOS / Android 原生只留后置占位,不进本轮发布 | 不通过项变成新一轮待办,不算发布完成 | +| G7 | 发布后运维与观察期通过 | 运维手册已交付;监控、日志、成本与配额口径已定并在跑;用户反馈已收集并归档;热修复记录齐全;回滚触发条件已写清且未被误触发(或已触发并按 G6 回滚方式处理) | 运维问题未闭环前不进 G8;小修走热修复回 G7,严重问题回 G6 / G5 | +| G8 | 迭代与规模化输入冻结 | 运维观察期结论已写(问题清单、热修复记录、回滚触发是否命中);v1.1 交接清单齐全(未修缺陷、开放问题、下一轮待办三项缺一不算齐);下一轮 G0-G6 的输入已冻结齐全 | 输入未冻结齐全不算 G8 完成;G8 的完成不是下一版已发布 | + +门禁衔接(v0.5):G6→G7 的条件是用户验收已确认(或不通过项已列入 +下一轮待办并经用户确认)+ 发布记录与回滚方式齐全 + 监控 / 日志 / +成本口径已定,三项缺一不进 G7。G7→G8 的条件是运维观察期结论已写 +(问题清单、热修复记录、回滚触发是否命中)+ v1.1 交接清单齐全, +两项缺一不进 G8。 + +## 已定口径:重心、跨视口、默认栈与开源优先(v0.5,本节优先于旧的多端写法) + +- **重心是 web + React + 多端自适应。** 首要交付是 React web 自适应 + (手机 / 平板 / 桌面浏览器宽度自适应),桌面端先以 web + PWA / + WebView 壳覆盖,不做已编译原生应用;iOS、Android 原生明确后置 + (iOS/Android 后置), + 只在 G8 新端接入时进一轮 G4c。本节与旧文“5 端并行”“按端发布” + 冲突处以本节为准,旧文的多端表述只作历史参考,不得再把 + iOS / Android 写成 MVP 交付端。 +- **G5 跨端 E2E 改为跨视口 E2E。** QA 第二部分不再是“跑遍各端”,而是 + 跨视口 E2E:同一任务、同一数据在手机 / 平板 / 桌面浏览器宽度下, + 结果、文案、状态词、同步状态是否一致。交付物仍叫跨端一致性矩阵, + 但矩阵的行是视口(手机 / 平板 / 桌面),不是原生端;不一致的标明 + 是缺陷还是刻意差异。未在任何视口实测的项单独列出,不写成通过。 +- **G6 按端发布改为 web 单端 + 后置原生占位。** 验收和发布只做 web + 单端;桌面先 web + PWA / WebView 壳,不做已编译原生应用; + iOS / Android 原生只留后置占位说明与 G8 接入条件,不进本轮发布、 + 不进本轮验收清单的“已发布”栏。未编译 / 未验证一律标注, + 不得写成已发布、已上架。 +- **开源优先。** 需要一个模块、组件、库时,先查开源,查完再自研: + 查许可证、维护状态、体积、安全四项;优先 MIT/Apache 类许可, + 避 SSPL / 商业重型许可;选型结论记入架构(技术栈表或决策记录), + 写清选了哪个开源项目、为什么没选其它、许可证是什么。开源优先 + 不是“能用开源就不用自研”的口号:查过、记过、许可证过关,才算 + 走完了开源优先;没查就自研,或查了不记,都算违规。 +- **默认后端是 TypeScript 全栈。** 新做产品的默认栈:前端 + Vite + React + TypeScript、后端 Fastify + TypeScript 严格模式、 + PostgreSQL、ORM 为 Drizzle 或 Prisma 二选一、测试 Vitest、 + API 用 OpenAPI 或共享类型。技术栈在 G2 冻结后不准中途换;只有 + 用户特别要求时才换语言(例如用户明确要求 Python 或 Go), + agent 不得以“更合适”为由自行换语言。换语言是用户特别要求的 + 例外,必须记入决策记录,写清是谁要求的、换成了什么。 +- **codex-app-server 本身保持 Python,不为统一语言重写。** 上面 + 的 TypeScript 默认栈只适用于本技能新做的产品,绝不适用于 + codex-app-server 本身;不要把新产品默认栈写成要重写现有系统, + 不要在 codex-app-server 仓库里以“统一语言”为由改语言。 + +## G7 发布后运维与观察期 + +G7 在 G6 之后、G8 之前,派生运维线程(附录 09-ops)。G7 不是 +“发布完就结束”,而是一段有结论的观察期。 + +- **监控:** 监控什么、阈值是多少、告警发给谁、多久看一次, + 四项在运维手册里写清;只写“已监控”不算数。 +- **错误:** 错误分级、复现步骤、归属线程、处理时限,记入问题清单; + 同一错误重复出现要升级,不静默放过。 +- **成本与配额:** 成本口径(按什么计费、按什么周期结算)、配额 + 上限、配额将满时的动作(先停新任务还是先问用户),在 G7 开始前 + 定好并在观察期里实测记录;成本超阈值回头问用户(见全自动模式 + 的四类回头问用户情形)。 +- **用户反馈收集:** 反馈渠道、收集周期、反馈如何变成待办(直接进 + 下一轮待办还是先记开放问题),写清;反馈不进待办就等于没收集。 +- **热修复回路:** 小修按回归清单重跑,不重开整轮。热修复的范围 + 是运维与热修复范围内的修补:修完只重跑回归清单里受影响的用例, + 回归通过即回 G7 继续观察;热修复绝不直接改契约,契约要改走 + 契约变更协议(版本号加一、回归任务),不悄悄分叉。 +- **回滚触发:** 回滚触发条件在运维手册里预先写清,例如严重错误 + 持续超阈值、核心链路不可用、成本 / 配额失控、数据损坏风险。 + 触发后按 G6 回滚方式处理:先停 web 端(按发布记录里写清的 + “出问题先停哪个端”)、回上一版本(revert 对应 PR 或重新部署 + 上一 tag),绝不 force-push 回退主线;回滚后重新走合并门 + 才能再发布。回滚触发是否命中,是 G7→G8 结论里必须写的一句, + 不写等于 G7 没结论。 +- **运维手册为交付物:** 运维手册模板见本节末尾;手册缺监控、 + 成本口径、回滚触发中任何一项,G7 不算通过。 +- **运维线程的边界:** 运维线程只写运维与热修复范围,不直接改契约、 + 不冒充发布。运维线程说“已发布新版”不算发布,发布仍由 G6 的 + 发布记录与用户确认界定;运维线程发现要改契约或要发新版时, + 交协调员走变更协议或下一轮待办,不自己推主线、自己发版。 +- **严重问题回路:** 热修复修不好的严重问题,不在 G7 里硬扛: + 回 G6(重新验收)或回 G5(重新联调回归),修完按门禁重新过 + G6 → G7;回路次数与原因记入观察期结论。 + +### 运维手册模板(正文版,附录 09-ops 同款) + +1. 服务与端:web 单端地址、部署方式、停端步骤(出问题先停哪个端)。 +2. 监控:监控项、阈值、告警接收人、查看周期。 +3. 日志:日志位置、保留期、查错步骤。 +4. 错误清单:分级、复现、归属、处理时限。 +5. 成本与配额:计费口径、配额上限、将满时的动作。 +6. 用户反馈:渠道、周期、转待办规则。 +7. 热修复:回归清单、热修复记录表。 +8. 回滚触发:触发条件、回滚触发是否命中、回滚方式(revert 或重部署上一 tag)。 + +## G8 迭代与规模化 + +G8 在 G7 之后,派生迭代线程(附录 10-iteration)。G8 的完成 +不是“下一版已发布”,是下一轮 G0-G6 的输入已冻结齐全。 +下一版没发布、但下一轮输入已冻结齐全,G8 算完成;下一版 +匆匆发布了、但下一轮输入没冻结,G8 不算完成。 + +- **v1.1 交接清单:** 三项缺一不算齐——① 未修缺陷(带归属和 + 严重程度)、② 开放问题(含任务间问答里未关闭的假设)、 + ③ 下一轮待办(G6 不通过项、G7 问题清单里未闭环项、用户反馈 + 转来的项汇总)。交接清单模板见本节末尾;G6 收尾时的 v1.1 + 交接清单是初版,G8 要把它更新为含 G7 结论的终版。 +- **契约 v1→v2 变更协议:** 下一轮契约要升版时,按“契约冻结与 + 变更协议”走:改什么、为什么、影响哪些端、是否向后兼容, + 四项写清,协调员批准后版本号加一(v1 -> v2),受影响端各收 + 回归任务;不批准的按旧契约做,差异记入已知问题。G8 只冻结 + 下一轮契约变更的输入(变更清单与兼容性结论),不直接在 G8 + 里改契约、发 v2。 +- **新端接入:** iOS / Android 原生以后才以新端身份进一轮 G4c, + 不塞进 MVP。接入条件在 G8 输入里写清:新端能力清单、与 web + 核心的复用关系、目标机器构建与验证步骤、未验证标注规则; + 新端接入仍走 G4c → G5 → G6 的门禁,不跳门禁直接算发布。 +- **规模与性能:** 下一轮规模目标(用户量、并发、数据量)、 + 性能基线与瓶颈、扩容或降级方案,写进下一轮输入;没有基线 + 的“能扩容”不算结论。 +- **废弃策略:** 要废弃的能力、接口、端,写清废弃时间表、替代 + 方案、用户通知方式;废弃不是悄悄删,先通知、再标记废弃、 + 再下线,三步缺一不算废弃完成。 + +### v1.1 交接清单模板(正文版,附录 10-iteration 同款) + +1. 未修缺陷:缺陷、归属、严重程度、复现步骤。 +2. 开放问题:问题、来源(任务间问答未关闭假设 / 用户反馈 / G7 观察)、 + 待谁确认。 +3. 下一轮待办:待办项、归属角色、对应 G0-G6 阶段。 +4. 契约变更输入:v1→v2 变更清单、向后兼容结论。 +5. 新端接入输入:新端清单、复用关系、验证步骤(iOS / Android 后置 + 占位在此更新为接入条件,不提前写成已交付)。 +6. 规模与废弃输入:规模目标、性能基线、废弃时间表。 ## 接单选型:协调员第一件事是问,不是写代码 @@ -172,8 +323,10 @@ G4 分阶段不是“慢”,是止损:web 先行验证核心链路和契约 问卷模板在 `templates/artifacts/intake-questions.md`。最关键的六问: 1. 目标用户是谁,agent 工具最核心的一到三个能力是什么? -2. 需要哪些客户端?从 web、macOS、Windows、iOS、Android 里选,可多选, - 也要问清是否接受“共享 Web 核心 + 各端壳”的路线。 +2. 需要哪些客户端?v0.5 默认只问 web(React、多视口自适应): + 从 web、macOS、Windows、iOS、Android 里选时,iOS / Android 原生 + 明确后置(iOS/Android 后置),不在 MVP 内选;也要问清是否接受 + “web 核心 + 桌面 web + PWA / WebView 壳”的路线。 3. MVP 砍到什么程度?账号、同步、离线、付费,哪些 v1 必须有、哪些明确不做? 4. **执行模型:agent 在哪里跑(本机 / 服务端 / 第三方 API)?谁付模型费用?** 5. **权限边界:agent 能读哪些文件、能写哪些目录、能上网吗、能跑 shell 吗?** @@ -202,9 +355,11 @@ G0 的六问缺一问,G0 就不算过。用户没回复时,协调员等, | UI/UX 设计 | 1 | `docs/design/` | 流程、页面、设计规范、跨端一致性规则 | | 后端 / API(如有) | 1 | `server/` | 按契约实现的服务端、鉴权与同步 | | 共享核心 | 1 | `packages/shared/`(G3) | 共享类型、SDK、mock 服务、契约测试 | -| 客户端开发 | 每客户端 1 | `apps/web`、`apps/macos`、`apps/windows`、`apps/ios`、`apps/android` 之一 | 该客户端可运行产物 + 自测证据 | -| QA / 测试 | 1(跨端 E2E 可再分 1 个) | `tests/` | 测试用例、跨端一致性矩阵、缺陷清单 | -| 验收 / 发布 | 协调员兼任,用户拍板 | `docs/release/` | 验收清单结果、按端发布说明、已知问题清单 | +| 客户端开发 | 每客户端 1 | `apps/web`、`apps/macos`、`apps/windows`、`apps/ios`、`apps/android` 之一 | 该客户端可运行产物 + 自测证据;v0.5 默认只开 web,iOS / Android 原生后置占位,不在 MVP 内 | +| QA / 测试 | 1(跨视口 E2E 可再分 1 个) | `tests/` | 测试用例、跨端一致性矩阵(v0.5 行是跨视口)、缺陷清单 | +| 验收 / 发布 | 协调员兼任,用户拍板 | `docs/release/` | 验收清单结果、web 单端发布说明、已知问题清单 | +| 运维 | 1(G7) | `docs/ops/` | 运维手册、问题清单、热修复记录、回滚触发结论 | +| 迭代 | 1(G8) | `docs/` | v1.1 交接清单终版、下一轮 G0-G6 输入冻结清单 | 角色模板的权威来源是本文件末尾的附录。附录随 SKILL.md 一起播种, 所以租户任务内一定能看到。`templates/roles/` 下的文件是编辑用的源文件, @@ -259,6 +414,9 @@ G0 的六问缺一问,G0 就不算过。用户没回复时,协调员等, 机制不依赖“模型会自动写标记块”这个假设: - 唯一事实来源是协调员维护的待办文件 `docs/swe-todos.md`, + 待办清单覆盖 G0-G8(G0 接单、G1 规划、G2 设计、G3 共享核心、 + G3.5 spike、G4a web、G4b 桌面壳、G4c 后置占位、G5 联调跨视口、 + G6 web 单端验收、G7 运维观察、G8 迭代输入冻结), 格式就是普通的 checkbox 清单(`- [ ] G4a web 冒烟通过`), 加项目待办(如果平台提供项目待办 API,协调员同步一份,不强求子线程会用)。 - 子线程绝不直接改待办文件。每个子线程的结尾报告必须带一节: @@ -387,9 +545,10 @@ tests/ # QA 线程专属,含跨端一致性用例 - 合并后删远程分支(本地分支同步清理),避免旧分支被误复用; 删分支前确认合并提交已在主线。 -### 发布与回滚:按端打 tag,绝不 force-push 回退 +### 发布与回滚:web 单端打 tag,绝不 force-push 回退 -- 按端发布时打 tag,例如 v0.1.0;发布说明从已合 PR 汇总,不凭记忆重写。 +- web 单端发布时打 tag,例如 v0.1.0;发布说明从已合 PR 汇总,不凭记忆重写。 + v0.5 不再默认按端分别发布;iOS / Android 原生后置占位不打发布 tag。 - 回滚是 revert 对应 PR,或重部署上一个 tag;绝不是 force-push 回退主线。 回滚后要重新走合并门(CI、评审)才能再发布,不要回滚完直接推。 @@ -411,24 +570,29 @@ tests/ # QA 线程专属,含跨端一致性用例 - QA 线程正式分两部分,各自交付物写死,缺一不算 G5 通过: ① 单端复核:逐端复核各客户端的自测证据是否属实(命令、结果、冒烟清单), 交付物是逐端复核报告(每端通过 / 不通过 + 证据 + 未复核项)。 - ② 跨端 E2E:同一 agent 任务、同一份数据跑遍各端,交付物是跨端一致性矩阵 - (各端结果、错误提示、同步状态是否一致)+ 缺陷清单 + 回归清单。 + ② 跨视口 E2E(v0.5 已定口径,原跨端 E2E 改为跨视口 E2E): + 同一 agent 任务、同一份数据跑遍手机 / 平板 / 桌面浏览器宽度, + 交付物是跨端一致性矩阵(矩阵的行是视口:各视口结果、文案、 + 状态词、同步状态是否一致)+ 缺陷清单 + 回归清单。 - agent 专属测试清单保留,归属如下,不能只测 happy path: 归单端复核(每端都要过):沙箱越界、危险动作审批、token / 配额超限; - 归跨端 E2E(同一任务跨端行为一致):长任务超时和取消、断网续跑、模型 503 重试。 + 归跨视口 E2E(同一任务跨视口行为一致):长任务超时和取消、断网续跑、模型 503 重试。 安全检查点在 G5 单独签字,检查权限边界和密钥处理,不算 QA 的附带项。 -- 未编译端的 QA 口径要写死:iOS / Android / Mac 在 Linux 主机上编不出来时, - QA 结论写“代码评审 + Web 核心验证”,不写“构建通过”。 +- 未编译 / 未验证的 QA 口径要写死:iOS / Android 原生后置占位 + 不进 QA 通过表;Mac 在 Linux 主机上编不出来时,QA 结论写 + “代码评审 + Web 核心验证”,不写“构建通过”,不写“已发布”。 - 验收清单模板在 `templates/artifacts/acceptance-checklist.md`。 - 验收人是用户,协调员只负责把清单和各端演示产物准备好, - 不能代替用户勾选通过。验收和发布按端分别做: - web 演示可真跑,未编译端审代码和构建步骤,两者效力不同,分开标注; - web 部署、桌面安装包分发、应用商店审核是三条流水线,分开记录回滚方式。 -- 每端上手文档是 G6 交付物之一:每端一份,写清启动、登录、核心流程、 + 验收人是用户,协调员只负责把清单和 web 演示产物准备好, + 不能代替用户勾选通过。验收和发布为 web 单端: + web 演示可真跑;iOS / Android 原生只留后置占位,不进本轮发布; + web 部署的回滚方式单独记录(先停 web 端、回上一版本), + 桌面安装包分发、应用商店审核不在本轮流水线内,不写成已走完。 +- 每端上手文档是 G6 交付物之一:web 版一份,写清启动、登录、核心流程、 常见问题;G4 阶段先写 web 版(G4a 交付时随 web 客户端一起交), - 桌面、移动版在各自 G4b / G4c 交付时补齐,不拖到 G6 才现写。 + 不拖到 G6 才现写;iOS / Android 原生后置,不在本轮补移动版上手文档。 - v1.1 交接清单是 G6 收尾必备,三项缺一不算收尾完成:未修缺陷 - (带归属和严重程度)、开放问题(含任务间问答里未关闭的假设)、下轮待办。 + (带归属和严重程度)、开放问题(含任务间问答里未关闭的假设)、下轮待办; + G8 要把这份清单更新为含 G7 结论的终版,三项缺一仍不算齐。 ## 失败、续跑与成本 @@ -443,16 +607,19 @@ tests/ # QA 线程专属,含跨端一致性用例 较经济的模型,具体以项目实际可用模型和配额为准; 配额将满时先停新线程,不先透支再解释。 -## 诚实边界:原生客户端 +## 诚实边界:原生客户端(v0.5 后置占位版) - 在只有 Linux 主机的环境里,PWA、“添加到主屏幕”、WebView 壳是能做能测的; 真原生 iOS 需要 Xcode、Android 需要 Android SDK、已编译的 Mac 应用 需要 Mac 环境,这些在当前 Linux VM 上编不出、测不了。 -- 所以客户端角色模板里有明确要求:编不出来的平台,交付物是 - Web 核心 + 该端壳代码 + 在目标机器上的构建步骤,并明确标注 - “未在目标机器上编译验证”,绝不能把“代码写完了”写成“应用已发布”。 -- 路线选择(真原生 / 跨平台壳 + Web 核心)必须在 G0 由用户定, - 不能由某个客户端线程中途自己改路线。 +- v0.5 后置占位:iOS / Android 原生不在 MVP 内,交付物不是 + “Web 核心 + 该端壳代码 + 在目标机器上的构建步骤”,而是后置占位说明: + 写清该端以后才接入、接入条件是什么、目标机器验证步骤待 G8 新端接入时 + 再定,并明确标注“未编译 / 未验证、未发布”。旧的“壳代码 + 构建步骤” + 写法自 v0.5 起废止,不得再把 iOS / Android 写成 MVP 交付端, + 绝不能把“代码写完了”写成“应用已发布”。 +- 路线选择(web + PWA / WebView 壳,iOS / Android 原生后置)必须在 G0 + 由用户定,不能由某个客户端线程中途自己改路线、自己把原生端加回 MVP。 ## 校验(协调员每过一个门禁自查一次) @@ -470,11 +637,23 @@ tests/ # QA 线程专属,含跨端一致性用例 发布打 tag 了吗,回滚方案是 revert 或重部署上一 tag、而不是 force-push 吗? 密钥进代码、commit、命令行了吗?.gitignore 在首 commit 前检查了吗? - 验收清单是不是用户亲手确认的?有没有一项是协调员替用户勾的? -- 分阶段走了吗?G3.5 没过就开了 G4b / G4c 吗? +- 分阶段走了吗?G3.5 没过就开了 G4b 吗?G4c 是不是仍被写成了 MVP 交付端? - v0.3 新增项:派生校验表 8 项全填且贴进了提示词吗?精简包所含章节 在提示词里列出了吗?QA 单端复核报告和跨端一致性矩阵都齐了吗? agent 测试清单归属对吗?决策记录是只追加的 `docs/decisions.md` 吗? web 版上手文档在 G4a 交了吗?v1.1 交接清单三项齐了吗? +- v0.5 新增项:G6→G7 的条件齐了吗(用户验收已确认或不通过项已列入 + 下一轮待办并经用户确认 + 发布记录与回滚方式齐全 + 监控 / 日志 / + 成本口径已定)?G7 运维手册齐了吗,热修复是不是只按回归清单重跑、 + 回滚触发是否命中写了吗?G7→G8 的条件齐了吗(运维观察期结论已写 + + v1.1 交接清单齐全)?G8 结论是不是“下一轮 G0-G6 输入已冻结齐全”, + 而不是“下一版已发布”?跨视口 E2E 的矩阵行是不是手机 / 平板 / 桌面 + 视口?开源优先查过许可证、维护状态、体积、安全并记入架构了吗, + 选型是不是优先 MIT/Apache、避 SSPL?默认栈是不是 TypeScript 全栈 + (Vite + React + TypeScript、Fastify + TypeScript 严格模式、 + PostgreSQL、Drizzle 或 Prisma 二选一、Vitest),G2 冻结后有没有 + 未经用户特别要求就换语言?iOS / Android 是不是仍写成后置占位, + 未编译 / 未验证有没有标注为未发布? 有一项为否,就停在当前门禁,不进入下一阶段。 ## 附录:角色模板(播种随附版) @@ -488,7 +667,10 @@ tests/ # QA 线程专属,含跨端一致性用例 本附录同时是 v0.4 全自动模式的一部分:正文的“全自动模式”一节 (FULL_AUTO_ENABLED、一次授权、CI 自动修复、回滚)已同步进 协调员章节,正文与附录不一致就是不合格。 -(附录正文由生成脚本从 `templates/roles/` 原样拼接,见 CHANGELOG。) +本附录同时是 v0.5 版的一部分:正文的 G7、G8、“已定口径” +(跨视口 E2E、开源优先、TypeScript 全栈、iOS / Android 后置) +已同步进协调员、QA、验收、运维、迭代章节,正文与附录不一致 +就是不合格。 --- @@ -513,10 +695,18 @@ full-auto-executor + installation id。质量门禁全部自动且阻塞合并 ## 你必须先做的事 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, 你核对证据后才勾选。不要虚构任何待办标记语法,不要依赖模型会自动写标记块。 @@ -542,16 +732,30 @@ full-auto-executor + installation id。质量门禁全部自动且阻塞合并 在 G3 阶段就参与契约测试,不要等到 G4 才对接。 - G3.5:可行性 spike。核心链路真跑通(agent 工具就是任务能创建、能跑出进度、 能取消、能回结果)才能扩端,跑不通先修核心或缩 MVP。 -- G4a:web 先行 1 个线程。G4b:桌面壳 macOS / Windows 各 1 个线程。 - G4c:移动端 iOS / Android 各 1 个线程。用户明确签字接受并行成本和风险时, - 才可以在记录里写明例外原因后并行开 G4b / G4c。 -- G5:QA 分单端复核和跨端 E2E,安全检查点单独签字。 +- 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 通过。 -- G6:你按端分别准备验收清单和演示产物,交用户逐项确认;发布和回滚也按端分开记。 + 跨视口 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 的输入 + 已冻结齐全。 ## 你的合并规则(评审与执行拆分) @@ -593,6 +797,8 @@ full-auto-executor + installation id。质量门禁全部自动且阻塞合并 每个门禁一份简短判定:过了哪个门、证据是什么、下一阶段派生哪几个线程、 有什么风险和未完成项。G6 的交付物是用户确认过的验收清单,不是你自己勾的清单。 +G7 的交付物是运维手册与观察期结论(含热修复记录、回滚触发是否命中); +G8 的交付物是 v1.1 交接清单终版与下一轮 G0-G6 输入冻结清单,不是下一版发布证明。 --- @@ -694,10 +900,21 @@ full-auto-executor + installation id。质量门禁全部自动且阻塞合并 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 存法、通知、文件权限)归各客户端线程,不要混成一层。 @@ -788,10 +1005,13 @@ TODO-UPDATE 要求,缺一项就不发任务)。派生提示词里的精简 按目标机器的构建步骤交付。没有 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 起废止。 ## 交付前自测(缺一项不算完成) @@ -867,7 +1087,7 @@ agent 类产品还要参与 G3.5 可行性 spike:任务能创建、能跑出 ## 附录角色:06-qa(来源 templates/roles/06-qa.md) -# 角色模板:QA / 测试(单端复核 + 跨端 E2E,可分 2 个线程) +# 角色模板:QA / 测试(单端复核 + 跨视口 E2E,可分 2 个线程) ## 只能写 @@ -881,12 +1101,14 @@ agent 类产品还要参与 G3.5 可行性 spike:任务能创建、能跑出 QA 正式分两部分,各自交付物写死,缺一不算 G5 通过: ① 单端复核:逐端复核各客户端的自测证据是否属实,交付物是逐端复核报告 (每端通过 / 不通过 + 证据 + 未复核项); - ② 跨端 E2E:同一 agent 任务、同一份数据跑遍各端,交付物是跨端一致性矩阵 - (各端结果、文案、状态词、同步状态是否一致;不一致的标明是缺陷还是刻意差异) + ② 跨视口 E2E(v0.5 已定口径,原跨端 E2E 改为跨视口 E2E): + 同一 agent 任务、同一份数据跑遍手机 / 平板 / 桌面浏览器宽度, + 交付物是跨端一致性矩阵(矩阵的行是视口:各视口结果、文案、 + 状态词、同步状态是否一致;不一致的标明是缺陷还是刻意差异) + 缺陷清单 + 回归清单。 2. agent 专属测试(缺一项不算测完),归属如下: 归单端复核(每端都要过):沙箱越界、危险动作审批、token / 配额超限; - 归跨端 E2E(同一任务跨端行为一致):长任务超时和取消、断网续跑、模型 503 重试。 + 归跨视口 E2E(同一任务跨视口行为一致):长任务超时和取消、断网续跑、模型 503 重试。 4. 安全检查点(G5 单独签字):权限边界是否按契约实现、密钥是否外泄、 agent 是否能读工作目录外文件。安全检查不算 QA 的附带项。 5. 缺陷清单:每个缺陷写清复现步骤、影响客户端、严重程度、归属线程。 @@ -895,14 +1117,15 @@ agent 类产品还要参与 G3.5 可行性 spike:任务能创建、能跑出 ## 未编译端的口径 -iOS / Android / Mac 在 Linux 主机上编不出来时,你的结论写 -“代码评审 + Web 核心验证”,不写“构建通过”。没测的端和用例单独列出, +iOS / Android 原生后置占位不进 QA 通过表,标注“未编译 / 未验证、 +未发布”;Mac 在 Linux 主机上编不出来时,你的结论写 +“代码评审 + Web 核心验证”,不写“构建通过”。没测的视口和用例单独列出, 不要把“没测”写成“通过”。 ## 完成定义 - 所有 PRD 验收标准都有对应测试用例,不是只测了 happy path。 -- 跨端矩阵已覆盖全部已选客户端,缺失的端要写明为什么没测。 +- 跨端矩阵已覆盖手机 / 平板 / 桌面全部视口,缺失的视口要写明为什么没测。 - 缺陷清单已交协调员,严重缺陷未修好前不建议进入验收。 ## 禁止 @@ -922,16 +1145,18 @@ iOS / Android / Mac 在 Linux 主机上编不出来时,你的结论写 1. 按 `templates/artifacts/acceptance-checklist.md` 生成本项目的验收清单, 每一项对应 PRD 里的一条验收标准,不额外加、不悄悄删。 -2. 每个已选客户端准备一份演示产物:怎么启动、测哪个核心流程、 - 已知问题是什么、哪些平台未编译验证。web 演示可真跑, - 未编译端审代码和构建步骤,两者效力不同,分开标注,不能混成一张“通过”表。 -3. 发布说明草稿,按端分别写:新能力、已知问题、回滚方式 - (至少写清“出问题先停哪个端”)。web 部署、桌面安装包分发、 - 应用商店审核是三条流水线,分开记录,不要写成一次全上。 -4. 每端上手文档:每端一份,写清启动、登录、核心流程、常见问题; - web 版在 G4a 交付时先交,桌面、移动版在各自 G4b / G4c 交付时补齐。 +2. 为 web 单端准备一份演示产物:怎么启动、测哪个核心流程、 + 已知问题是什么、哪些平台未编译验证。web 演示可真跑; + iOS / Android 原生只留后置占位,不进本轮演示产物,不混成一张“通过”表。 +3. 发布说明草稿,web 单端写:新能力、已知问题、回滚方式 + (至少写清“出问题先停 web 端”)。web 部署的回滚方式单独记录; + 桌面安装包分发、应用商店审核不在本轮流水线内,不写成已走完。 +4. 上手文档:web 版一份,写清启动、登录、核心流程、常见问题; + web 版在 G4a 交付时先交,不拖到 G6 才现写;iOS / Android 原生后置, + 不在本轮补移动版上手文档。 5. v1.1 交接清单:未修缺陷(带归属和严重程度)、开放问题 - (含任务间问答里未关闭的假设)、下轮待办;三项缺一不算 G6 收尾完成。 + (含任务间问答里未关闭的假设)、下轮待办;三项缺一不算 G6 收尾完成; + G8 要把它更新为含 G7 结论的终版,三项缺一仍不算齐。 ## 用户确认规则 @@ -951,8 +1176,9 @@ iOS / Android / Mac 在 Linux 主机上编不出来时,你的结论写 ## 按端发布与回滚(验收) -- 发布按端分别做:每端发布时打 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 运行链接、执行人缺一项, @@ -991,3 +1217,110 @@ iOS / Android / Mac 在 Linux 主机上编不出来时,你的结论写 - 不在共享逻辑里写某端专属代码,专属逻辑留给各端适配器。 - 不改契约迎合实现;实现不了契约时向协调员提变更请求。 + +--- + +## 附录角色:09-ops(来源 templates/roles/09-ops.md,v0.5 新增) + +# 角色模板:运维(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 后置仍是后置占位, + 不在本轮运维里把原生端写回交付端。 + +--- + +## 附录角色:10-iteration(来源 templates/roles/10-iteration.md,v0.5 新增) + +# 角色模板:迭代(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/tests/test_software_engineering_g7g8.py b/cloud/tests/test_software_engineering_g7g8.py new file mode 100644 index 0000000..ba1942e --- /dev/null +++ b/cloud/tests/test_software_engineering_g7g8.py @@ -0,0 +1,82 @@ +"""software-engineering 技能 v0.5:G7/G8 关键词断言(轻量)。 + +只断言正文与附录都含有 v0.5 的关键概念,不逐字背诵全文: +版本号与上一版、G7 运维与 G8 迭代、运维手册与 v1.1 交接清单、 +热修复与回滚触发、跨视口 E2E、开源优先与许可证口径、 +TypeScript 默认栈与用户特别要求例外、iOS/Android 后置。 +正文改了附录没同步时,附录部分就会失败。 +门禁衔接断言单独检查:G6→G7 与 G7→G8 的条件词必须同时 +出现在正文门禁表附近与附录协调员章节。 +角色断言检查附录含 09-ops 与 10-iteration 章节标题。 +""" + +import unittest +from pathlib import Path + +SKILL = Path(__file__).resolve().parents[1] / "skills" / "software-engineering" / "SKILL.md" + +# 正文与附录都要有的关键词(词形与技能正文一致) +BOTH = ("v0.5", "G7", "G8", "运维手册", "v1.1 交接清单", + "热修复", "回滚触发", "跨视口", "开源优先", "MIT/Apache", + "SSPL", "TypeScript", "Fastify", "Drizzle 或 Prisma", + "Vitest", "用户特别要求", "iOS/Android 后置") + +# 门禁衔接:正文与附录协调员章都要出现 +GATES = ("G6→G7", "G7→G8") + + +class SoftwareEngineeringG7G8TestCase(unittest.TestCase): + def test_g7g8_in_body_and_appendix(self): + text = SKILL.read_text(encoding="utf-8") + main, sep, appendix = text.partition("## 附录:角色模板") + self.assertTrue(sep, "appendix marker missing") + self.assertIn("v0.4", main, "header must name the previous version") + self.assertIn("全自动模式", main, "header must keep v0.4 full-auto content") + self.assertIn("v0.3", main, "header must keep v0.3 content") + for kw in BOTH: + self.assertIn(kw, main, kw) + self.assertIn(kw, appendix, "appendix: " + kw) + + def test_gate_transitions_in_body_and_coordinator(self): + text = SKILL.read_text(encoding="utf-8") + main, sep, appendix = text.partition("## 附录:角色模板") + self.assertTrue(sep, "appendix marker missing") + # 附录协调员章:从 00-coordinator 到下一个附录角色标题之间 + coord_start = appendix.index("00-coordinator") + coord_end = appendix.index("## 附录角色:01-", coord_start) + coordinator = appendix[coord_start:coord_end] + for kw in GATES: + self.assertIn(kw, main, kw) + self.assertIn(kw, coordinator, "coordinator appendix: " + kw) + # 门禁条件词:G6→G7 侧与 G7→G8 侧的关键条件 + self.assertIn("用户验收已确认", main) + self.assertIn("用户验收已确认", coordinator) + self.assertIn("运维观察期结论已写", main) + self.assertIn("运维观察期结论已写", coordinator) + self.assertIn("回滚触发是否命中", main) + self.assertIn("回滚触发是否命中", coordinator) + + def test_g7g8_roles_in_appendix(self): + text = SKILL.read_text(encoding="utf-8") + _, sep, appendix = text.partition("## 附录:角色模板") + self.assertTrue(sep, "appendix marker missing") + self.assertIn("## 附录角色:09-ops", appendix) + self.assertIn("## 附录角色:10-iteration", appendix) + self.assertIn("下一轮 G0-G6", appendix) + self.assertIn("不是下一版已发布", appendix) + self.assertIn("不直接改契约", appendix) + + def test_g7g8_templates_in_body_and_appendix(self): + text = SKILL.read_text(encoding="utf-8") + main, sep, appendix = text.partition("## 附录:角色模板") + self.assertTrue(sep, "appendix marker missing") + self.assertIn("运维手册模板", main) + self.assertIn("运维手册模板", appendix) + self.assertIn("v1.1 交接清单模板", main) + self.assertIn("v1.1 交接清单模板", appendix) + self.assertIn("未修缺陷", main) + self.assertIn("未修缺陷", appendix) + + +if __name__ == "__main__": + unittest.main()