Files
codex-app-server/cloud/skills/software-engineering/SKILL.md
T
host 0072e1ae6a skill: cross-task artifact pass with sha256 dual-channel verification
Core artifacts travel as an explicit manifest; coordinator triple-checks
(core report vs manifest vs recomputed hash) before cleanup, regression
rewrites files verbatim, recomputes sha256, stops on ARTIFACT-HASH-MISMATCH
and only then runs the same core code plus import-only regression tests.
2026-11-03 02:48:55 +00:00

1480 lines
95 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: software-engineering
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 派生占位符必填表
(缺一项就不发任务)、P1-3 QA 正式分单端复核与跨端 E2E 两部分
(各自交付物写死)、P1-4 子任务精简包裁剪规则(只给本端相关章节,
提示词里列出所含章节);P2:任务间问答默认策略、决策记录落盘
`docs/decisions.md`、每端上手文档、v1.1 交接清单。
版本 v0.4(本分支,堆叠在 v0.3 之上:v0.3 仍 OPEN 时先合 v0.3
再合本分支,绝不丢 v0.3 内容):新增全自动模式(见“全自动模式”
一节):用户只碰需求、方案选择、一次 GitHub 授权、最后交付验收,
中间由主机自动执行器(`cloud/full_auto.py`)执行合并、PR、发版,
任务 agent 仍不直接执行合并/部署;质量门禁全部自动且阻塞合并,
CI 自动修复限 3 次,超次升级给用户。
装机路径见同目录 `README.md`:源码位置是 `cloud/skills/software-engineering/SKILL.md`,
播种后租户内位置是 `<codex-home>/skills/software-engineering/SKILL.md`。
## 何时用
- 用户说“做一款某某工具 / 应用 / agent 工具”,且涉及 2 个以上客户端。
- 用户说“按软件工程流程来”,或明确要产品规划、设计、开发、测试、验收全套。
- 已有产品要新增一个以上客户端,且需要统一契约和跨端一致性。
## 何时不用
- 只改一个 bug、只加一个小功能、只问某个技术怎么写:不用整套流程。
- 用户只想要一个快速原型验证想法:先走原型,验证通过后再用本技能转正式工程。
## 核心原则(协调员和所有角色线程都必须遵守)
1. **先冻结,后并行。** 客户端线程开工前,必须先有冻结的 PRD 和冻结的共享契约。
没有冻结契约就并行,5 个客户端一定各做各的接口,最后合不起来。
2. **一个线程只拥有一个目录。** 每个角色线程只能写自己被分配的目录,
共享契约和他人目录只读。想改共享部分,走契约变更协议,不直接改。
3. **协调员评审,执行与任务 agent 拆分。** 子线程做完先交分支和自测证据,
协调员评审、对照验收清单后给出合并决定;任务 agent 绝不直接执行
合并、PR 合并、部署,不冒充执行人。默认模式下,真正的合并、PR 合并、
部署由人或宿主操作执行,合并记录执行人写人或宿主操作。
全自动模式下(见“全自动模式”一节),执行人是主机自动执行器
(`cloud/full_auto.py`,需 FULL_AUTO_ENABLED 显式开启 + 已验证的
GitHub App installation),合并记录执行人写 full-auto-executor +
installation id,不写任务 agent 的名字。两种模式的执行人必须如实写,
写错就是冒充。
4. **状态以协调员维护的待办为准,不以聊天记忆为准。**
具体机制见“待办机制”一节。子线程不直接改待办文件,
只在结尾报告里写 TODO-UPDATE,协调员核对证据后才勾选。
5. **验收不能自证。** 开发线程说“做完了”不算完成,QA 线程的跨端测试
加用户的验收确认才算完成。做不出来的包、编不出来的原生应用,
必须明说,不能写成“已完成”。
6. **先验证最难的,再扩端。** 核心链路(对 agent 工具就是“任务能跑、
能取消、能回结果”)没跑通前,不开 5 端并行;先 web 验证,
再扩桌面壳,最后扩移动端。
## 全自动模式(API 优先、一次授权)
用户只碰四件事,中间不再碰 git/GitHub:① 一次需求;② 一次方案选择
(协调员给出 2-3 个方案:范围、技术栈、分阶段、时间成本,用户点一个);
③ 一次 GitHub 授权(GitHub App 安装,见下);④ 最后交付验收
(用户按验收清单逐项确认,不通过项自动变新一轮待办)。
只有四类情况回头问用户:成本超阈值、删数据/改权限/对外账号、
外部服务要人工验证、自动修复连续失败。其它中间问题(分支、PR、CI、
部署、回滚)一律由工具 + 技能 + LLM 在门禁内解决,不再问用户。
- **执行人是主机自动执行器,不是任务 agent。** 协调员只给合并决定,
合并、PR、发版、回滚由宿主侧 `cloud/full_auto.py` 执行,门控是
FULL_AUTO_ENABLED 显式开启 + 已验证的 GitHub App installation,
两者缺一执行器就拒绝,默认关闭。任务 agent 的工具仍是 shell /
文件 / MCP,宿主侧的合并、发 PR、部署不在任务 agent 工具列表内,
本技能不虚构这个能力,也不把执行器的工作写成任务 agent 做的。
- **一次授权的含义(API 优先)。** 控制台 OAuth 登录只证明本站身份,
不带来 GitHub 权限;GitHub 权限靠 GitHub App 安装,仓库范围靠安装时
选 All repositories 一次覆盖现有与未来仓库,能力范围受 App 声明的
权限封顶,新增权限必须改 App 声明并由安装方在 GitHub 重新接受,
无法静默升级。缺权限的动作直接拒绝并记为 needs_reaccept,不静默降级。
一次授权后系统全部走 GitHub API 自动做:建分支、提 PR、等 CI、
CI 失败自动修、rebase、合并、删分支、打 tag、写 release notes、
失败回滚到上一 tag。token 只进子进程环境/HTTP 请求头,不进命令行、
不进文件、不进审计记录(见 `cloud/full_auto.py` 的脱敏规则)。
- **一次授权后 API 自动配置(建仓分支要诚实)。** 顺序是:确保仓库、
设默认分支、开分支保护(要求 PR + 要求状态检查 strict + 禁止
force-push + 禁止删除 + 管理员同样受约束)、加 CI 工作流文件、
核对 App 级 webhook(App manifest 的 hook_attributes 已配好,
仓库级不再重复建 hook,重复建会双发)。建仓分两条路:组织安装 +
administration 写权限时,App token 可经 POST /orgs/{org}/repos
建组织仓;用户个人账号仓的 POST /user/repos 需要用户 token,
installation token 做不了——此时该步记为安装会话里唯一的人工步
(用户在同一次安装会话里先建一个空仓,App 以 All repositories
安装后即覆盖它),此后全部走 API,不再需要人工。把这一步说成
“App 已自动建仓”就是冒充,必须如实记为 needs_user_once。
- **绝不做网页自动化自动注册 GitHub 账号。** GitHub 服务条款禁止
自动化创建账号,注册有验证码、邮箱验证、可能的人机/手机验证,
绕验证码会触发封号,账号一封产品仓库都会丢。替代方案已定:
用户先人工建一次账号(如果还没有),然后点一次 GitHub App 安装授权,
从那一刻起全部走 API。浏览器自动化只留作 API 覆盖不到的配置页面
兜底,不用来注册账号、不用来绕验证码。向用户索取 GitHub 密码或
个人 token 明文同样禁止,复用已有的 App 安装流程,不另起一套
密码抓取流程。
- **护栏(即使授权给到最大,也必须有)。** 禁止删库、禁止 force-push
(含主分支)、禁止改仓库可见性、禁止读/外泄密钥、禁止删分支保护、
禁止绕分支保护,未知动作一律拒绝;主分支保护强制开;所有合并、
部署、发版写审计记录;用户可一键吊销安装(吊销后执行器立即拒绝)。
- **质量门禁全部自动且阻塞合并。** CI 全绿 + 目录隔离检查 + 契约版本
+ 协调员批准,四项缺一就不合并(判定见 `cloud/full_auto.py`
的 merge_gate,调用方把 pr/checks 结果传进来,不靠口头说通过)。
门禁不过时走 CI 自动修复循环:失败 -> 取 checks 定位 -> 修 -> 重跑,
限 3 次,超次升级给用户,不无限重试烧模型费。
- **回滚不靠 force-push。** 回滚只能是 revert PR 或重新部署上一 tag,
绝不 force-push 主分支。
- **交付报告。** 全自动链结束时交:仓库链接、release tag、演示产物、
验收清单、已知问题、成本、审计记录摘要。不通过项自动变新一轮待办,
不算发布完成。
## 阶段 DAG(不是所有线程同时开,是按门禁、分阶段开)
```
G0 接单选型 ──> G1 产品规划 ──> G2 产品设计 + 架构 ──> G3 共享核心
│ │ │ │
客户端清单 PRD 冻结 契约 v1 冻结 SDK / 契约实现
+ 执行模型 + 能力边界 + 状态机 + mock 服务
+ 权限边界 + 失败故事 + 错误 taxonomy + 契约测试
+ 审批模型 + 成本故事 + 技术栈表
+ 能力矩阵
│
G3.5 可行性 spike
核心链路真跑通
(跑不通不扩端)
│
G4a web 先行
│
G4b 桌面壳(先 web + PWA / WebView 壳,
不做已编译原生应用)
│
G5 联调 + 跨视口测试
↑ │
└── 缺陷回 G4 修,
修完回 G5 回归
│
G6 web 单端验收 + web 单端发布
(iOS / Android 原生后置占位,
不在 MVP 交付端内)
│
G7 发布后运维与观察期
↑ │
├── 热修复回 G7(小修按回归清单重跑,
│ 不重开整轮)
└── 严重问题回 G6 / G5(见 G7 一节)
│
G8 迭代与规模化
│
下一轮 G0-G6 输入冻结
(新端接入时再开一轮 G4c,
iOS / Android 原生以后才以新端身份进)
```
G4 分阶段不是“慢”,是止损:web 先行验证核心链路和契约,
桌面复用已验证的契约和 Web 核心,返工面最小。
原 G4c 移动端(iOS / Android)自 v0.5 起改为后置占位:iOS / Android
原生明确后置,不在 MVP 链内、不作为 MVP 交付端,只在 G8 新端接入时
再开一轮 G4c。用户明确签字“接受多端并行成本和风险”时,协调员可以
在记录里写明例外原因后并行开 G4a / G4b,但默认不并行,且该例外
绝不把 iOS / Android 原生重新写回 MVP 交付端。
## 门禁表
| 门 | 名称 | 通过标准 | 没通过怎么办 |
|----|------|----------|--------------|
| 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 服务和契约测试** | 客户端线程等共享线程,不自己各写一套 |
| G3.5 | 可行性 spike 通过 | 核心链路在真实(或最接近真实的)环境里跑通:以 agent 工具为例,任务能创建、能跑出进度、能取消、能回结果;跑不通的原因已定位到模型、沙箱、后端三者之一 | 不进入 G4,先修核心链路或缩 MVP,不扩端摊成本 |
| G4a | web 先行完成 | web 客户端满足角色模板的完成定义,有可运行产物或明确的未完成项 | 只重开 web 线程,不提前开桌面和移动 |
| G4b | 桌面壳完成 | macOS / Windows 各满足完成定义,未编译项已标注验证步骤 | 只重开失败的那端 |
| 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. 规模与废弃输入:规模目标、性能基线、废弃时间表。
## 接单选型:协调员第一件事是问,不是写代码
用户只说“做一款 agent 工具”时,协调员必须先问清下面这些,再建项目。
问卷模板在 `templates/artifacts/intake-questions.md`。最关键的六问:
1. 目标用户是谁,agent 工具最核心的一到三个能力是什么?
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 吗?**
6. **审批模型:删文件、改配置、发网络请求等危险动作前,是否逐项要人确认?
哪些动作可以自动做,哪些必须停下来等用户?**
选完客户端后,协调员把选择写成项目决策(不是只留在对话里),
再按阶段派生线程。用户中途改选客户端,属于范围变更:要重新评估
契约和排期,不能悄悄加一个线程了事。
G0 的六问缺一问,G0 就不算过。用户没回复时,协调员等,不按假设推进,
状态保存在待办里。
建仓是 G0 之后、G1 之前的前置任务,不是 G1 里的顺带事:
新产品先建仓,首 commit 只含仓库骨架(README、.gitignore、目录骨架),
不含业务代码,首 commit 落到默认分支后,后续业务工作一律走分支加 PR;
已有仓库先核对 owner/repo、默认分支(以仓库实际 default_branch 为准,不猜)、
可见性与 PRD 一致,不一致先改 PRD 或换仓库,不要边开发边改仓库地址。
## 角色线程矩阵
| 角色 | 线程数 | 负责目录 | 产出 |
|------|--------|----------|------|
| 协调员 | 1,全程 | 不直接写业务代码,只写决策、待办、验收清单、合并决定 | 阶段计划、门禁判定、合并记录 |
| 产品经理 | 1 | `docs/` | PRD、用户故事、MVP 与不做清单 |
| 架构师 | 1 | `contracts/`、`packages/shared/`(冻结前) | API 契约、数据模型、agent 协议、仓库布局、状态机 |
| 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` 之一 | 该客户端可运行产物 + 自测证据;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/` 下的文件是编辑用的源文件,
发布前必须核对附录和源文件一致,不一致时以附录为准并先修源文件。
协调员派生子任务时,必须把对应角色模板全文贴进子任务提示词,
并补上本任务的输入、目录、分支和完成定义。
只写一句“按 software-engineering skill 做”是不够的,
子任务不一定会读到本技能。
## 协调员派生子任务的必填字段
每个子任务提示词必须包含,缺一项就不派生:
1. 角色模板全文(来自本文件附录,租户任务内可直接引用)。
2. 本阶段输入:PRD 哪个版本、契约哪个版本、设计稿哪个版本。
3. 拥有目录:只能写这一个目录;只读目录:契约、他人目录。
4. 分支名:`feat/swe/<阶段>-<角色>-<简称>`,例如 `feat/swe/client-web`、
`feat/swe/contract-v1`。子线程不直接推主线。
5. 完成定义:产出文件清单 + 必须跑过的自测命令 + 必须提交的证据。
6. 禁止事项:不改共享契约、不改他人目录、不编造构建结果、
不把“本地能跑”写成“已发布”。
7. 结尾必须带 TODO-UPDATE 小节(见“待办机制”),缺这节视为交付不完整。
派生前校验表(必填表,协调员必须把填好的表原样贴进派生提示词,
不能只在心里过一遍;缺一项就不发任务):
| 必填项 | 填什么 |
|--------|--------|
| 客户端名 | 本客户端,例如 web / macOS / Windows / iOS / Android |
| 拥有目录 | 只能写这一个目录,例如 `apps/web` |
| 分支名 | `feat/swe/<阶段>-<角色>-<简称>`,例如 `feat/swe/client-web` |
| 契约版本 | 冻结的契约版本号,例如 v1 |
| PRD 版本 | 冻结的 PRD 版本号 |
| 设计版本 | 冻结的设计版本(设计页清单见精简包) |
| 完成定义 | 产出文件清单 + 必须跑过的自测命令 + 必须提交的证据 |
| TODO-UPDATE 要求 | 结尾报告必须带 TODO-UPDATE 小节,格式见“待办机制” |
子任务精简包(裁剪规则写死,不是“尽量精简”):只给本端相关的
契约章节、设计页、PRD 故事和冻结决策摘要,绝不把 PRD、契约、
设计全文复制给每个线程。精简包由四部分组成,缺一部分就补齐再发:
① 本端相关的契约章节(列出章节号 / 标题);② 本端相关的设计页
(列出页名);③ 本端相关的 PRD 故事(列出故事编号);④ 冻结决策摘要
(不超过 10 条,列出决策标题)。派生提示词里必须列出精简包所含章节
清单,例如“契约 §任务状态机、§错误码;设计 p2 审批页;PRD 故事 S1、S3;
决策 D1、D4”——只写“已精简”不算数。线程发现缺章节时向协调员要补发,
不自己猜、不去全文里翻旧版。
## 待办机制(不依赖提示词注入)
本技能不虚构任何待办标记语法。标记工具此前因提示词膨胀被故意
不注入系统提示,只有提示词写明格式模型才会用,所以本技能的待办
机制不依赖“模型会自动写标记块”这个假设:
- 唯一事实来源是协调员维护的待办文件 `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,协调员同步一份,不强求子线程会用)。
- 子线程绝不直接改待办文件。每个子线程的结尾报告必须带一节:
```
TODO-UPDATE
- 完成:<待办项原文>,证据:<命令 / 文件 / 结果>
- 未完成:<待办项原文>,原因:<一句话>
- 新增:<新发现的待办项>,归属:<角色>
```
- 协调员收到报告后核对证据,证据对得上才勾选,证据对不上打回补证据。
协调员是待办文件的唯一写作者,避免 5 个线程同时改一份清单互相覆盖。
- 如果平台在子任务提示词里确实注入了待办标记工具,子线程可以在
TODO-UPDATE 之外再用标记工具,但 TODO-UPDATE 仍是必备项,
不能只写标记块就不写报告节。
## 契约冻结与变更协议
- 冻结前:架构线程可以自由改契约,改完要通知协调员更新版本号。
- 冻结物(G2 必须齐):API 契约、数据模型、agent 协议、
任务状态机、错误 taxonomy、技术栈表、每端能力矩阵。
任务状态机至少包含:创建、排队、运行中、等审批、已完成、
已取消、失败、超时;错误 taxonomy 至少区分:模型失败、工具失败、
用户取消、超时、权限拒绝、配额超限。同一错误在各端不得换一个名字。
- 冻结后:任何线程想改契约,必须给协调员发任务间消息,写清:
改什么、为什么、影响哪些客户端、是否向后兼容。
- 协调员批准后:契约版本号加一(v1 -> v2),架构线程改契约,
受影响的客户端各收到一条变更通知和一个回归任务。
- 协调员不批准:提议线程按旧契约做,差异记入已知问题,不悄悄分叉。
## 任务间问答默认策略与决策记录(v0.3 新增)
- 任务间问答默认策略:被问题卡住的线程先按冻结契约做,把假设写成
开放问题记入结尾报告,不无限等协调员答复、不停工等、不按猜测改契约。
协调员在下一轮答复:确认假设、纠正假设(发回归任务)、或升级为契约变更;
答复本身也要记入决策记录。等答复期间线程不阻塞在原地,先做契约内
无争议的部分。
- 决策记录落盘路径:`docs/decisions.md`,由协调员维护,子线程只在报告里
提议、不直接改。只追加不改写历史:一条决策写清日期、议题、决定、理由、
影响端;推翻旧决策时追加新条写明“取代 D-n”,绝不改旧条原文、不删旧条。
决策记录是合并记录和验收清单之外的第三份事实来源,口头决定不算数。
## 目录与分支规则
推荐的单仓布局(单客户端项目可删掉不需要的 `apps/*`):
```
docs/ # PRD、决策、设计、发布说明、待办(产品、设计、协调员)
contracts/ # API 契约、数据模型、agent 协议、状态机(架构,冻结后协调员所有)
packages/shared/ # 共享类型、API SDK(G3 共享核心线程;冻结后改动走变更协议)
apps/web/ # Web 客户端线程专属
apps/macos/ # macOS 客户端线程专属
apps/windows/ # Windows 客户端线程专属
apps/ios/ # iOS 客户端线程专属
apps/android/ # Android 客户端线程专属
server/ # 后端线程专属(如有)
tests/ # QA 线程专属,含跨端一致性用例
```
- 每个客户端线程只写自己的 `apps/<client>/`,共用组件只能通过
`packages/shared/` 引用,不能跨目录复制粘贴一份再各改各的。
- 共享核心要拆两层:共享逻辑(状态机、事件解析、重试策略)归共享核心线程;
各端适配器(token 存法、通知、文件权限)归各客户端线程。
- 合并顺序:共享核心先合,客户端按“自测通过 -> 协调员评审 -> CI 通过
-> 执行合并”依次合,执行人默认是人 / 宿主操作,全自动模式下是
主机自动执行器(FULL_AUTO_ENABLED + 已验证 installation,执行人记为
full-auto-executor + installation id,绝不记成任务 agent),冲突由协调员判定,
不由子线程自行解决后静默推主线。
- 目录隔离必须有自动化检查,不能只靠人工评审、不能只写“人工评审”。
合并前由人 / 宿主跑(以拥有目录 `apps/web` 为例,基线以合并目标分支
的最新 HEAD 为准):
```
git fetch origin
git diff --name-only $(git merge-base origin/main HEAD)...HEAD
```
逐项核对输出的每个文件是否落在拥有目录内;契约变更经协调员批准的
文件除外,但批准记录必须能对应到具体文件。检查命令、输出文件清单、
例外批准记录必须原样记入合并记录,缺检查输出的合并记录视为不合格,
不给合并决定。在 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 通过、禁止直接推。目标仓库没开保护时,
协调员要在决策记录里写明风险并去开通,不能假装已保护,
不能靠“大家自觉”代替保护。
- 合并门禁(2026-10-30 补,代码在 cloud/merge_gate.py,服务端
POST /tasks/{id}/merge 已接线;2026-10-31 硬门禁轨加
cloud/merge_gate_hard.py):保护状态只能由调用方或环境变量
CLOUD_BRANCH_PROTECTION 显式声明,代码不去 GitHub 核实、不声称
已保护。模式只由环境变量 CLOUD_MERGE_GATE_MODE 控制,默认
hard:上面五项全查,缺一 409 且任务状态不变,并写
merge_gate_blocked 审计;无证据不放行;unknown 不等于
protected,同样阻断;未保护即使带显式确认也不放行。record /
enforce / off 必须显式设置才生效(过渡/显式降级):record 下
未保护时须显式确认(merge_gate_confirm)才放行,无确认阻断,
无证据调用仍按旧接口放行;enforce 模式下未保护一律阻断,
确认也不放行——切 enforce 前必须先由用户决定并开通保护
(升级 Pro、公开仓库、或保持纪律 + 记风险,三者用户侧定,
代码不替选,操作说明与 payload 见
docs/merge-gate-branch-protection.md)。显式确认只覆盖保护风险,
绝不覆盖目录隔离违规;目录检查复用 v0.3 的 git diff --name-only
口径,越目录只能靠契约变更批准文件放行。技能播种仍只复制
SKILL.md,不做整目录复制(租户已改文件绝不被覆盖,见
cloud/skill_seed.py 的评估结论)。
### 合并方式与合并记录
- 默认 merge commit,不用 squash 或 rebase 改写分支历史口径
(仓库另有约定且协调员记录在案时除外)。
- 合并记录必须含:PR 号、合并提交 hash、CI 运行链接、执行人。
执行人是人或宿主操作,不是“协调员任务自己合”。
- 合并后删远程分支(本地分支同步清理),避免旧分支被误复用;
删分支前确认合并提交已在主线。
### 发布与回滚:web 单端打 tag,绝不 force-push 回退
- web 单端发布时打 tag,例如 v0.1.0;发布说明从已合 PR 汇总,不凭记忆重写。
v0.5 不再默认按端分别发布;iOS / Android 原生后置占位不打发布 tag。
- 回滚是 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 时,按仓库的密钥轮换流程处理并记录,
不靠改写历史掩盖(已公开的历史不能靠改写抹掉)。
## 测试与验收
- 每个客户端线程交付前必须自测:单元测试 + 对接契约的集成测试
+ 一份手工冒烟清单(启动、登录、核心 agent 任务、异常提示)。
- QA 线程正式分两部分,各自交付物写死,缺一不算 G5 通过:
① 单端复核:逐端复核各客户端的自测证据是否属实(命令、结果、冒烟清单),
交付物是逐端复核报告(每端通过 / 不通过 + 证据 + 未复核项)。
② 跨视口 E2E(v0.5 已定口径,原跨端 E2E 改为跨视口 E2E):
同一 agent 任务、同一份数据跑遍手机 / 平板 / 桌面浏览器宽度,
交付物是跨端一致性矩阵(矩阵的行是视口:各视口结果、文案、
状态词、同步状态是否一致)+ 缺陷清单 + 回归清单。
- agent 专属测试清单保留,归属如下,不能只测 happy path:
归单端复核(每端都要过):沙箱越界、危险动作审批、token / 配额超限;
归跨视口 E2E(同一任务跨视口行为一致):长任务超时和取消、断网续跑、模型 503 重试。
安全检查点在 G5 单独签字,检查权限边界和密钥处理,不算 QA 的附带项。
- 未编译 / 未验证的 QA 口径要写死:iOS / Android 原生后置占位
不进 QA 通过表;Mac 在 Linux 主机上编不出来时,QA 结论写
“代码评审 + Web 核心验证”,不写“构建通过”,不写“已发布”。
- 验收清单模板在 `templates/artifacts/acceptance-checklist.md`。
验收人是用户,协调员只负责把清单和 web 演示产物准备好,
不能代替用户勾选通过。验收和发布为 web 单端:
web 演示可真跑;iOS / Android 原生只留后置占位,不进本轮发布;
web 部署的回滚方式单独记录(先停 web 端、回上一版本),
桌面安装包分发、应用商店审核不在本轮流水线内,不写成已走完。
- 每端上手文档是 G6 交付物之一:web 版一份,写清启动、登录、核心流程、
常见问题;G4 阶段先写 web 版(G4a 交付时随 web 客户端一起交),
不拖到 G6 才现写;iOS / Android 原生后置,不在本轮补移动版上手文档。
- v1.1 交接清单是 G6 收尾必备,三项缺一不算收尾完成:未修缺陷
(带归属和严重程度)、开放问题(含任务间问答里未关闭的假设)、下轮待办;
G8 要把这份清单更新为含 G7 结论的终版,三项缺一仍不算齐。
## 失败、续跑与成本
- 任务中断后:先看它有没有实际进度。有进度走断点续跑;
从未开始的任务走全新重跑,不要用“拒绝续跑”把没开始的任务直接判死。
- 单个客户端失败不拖垮全局:只重开失败的客户端线程,
其他已完成的客户端不重做,契约不变就不用全量回归。
- G5 缺陷回路:缺陷回对应客户端或架构线程修,修完回 G5 回归,
回归范围按契约变更影响面定,不是每次都全量重测。
- 成本控制:分阶段本身就是成本控制。G4a 先验证,G4b / G4c 复用已验证物;
协调员、产品、架构用较强模型,重复性强的客户端实现和 QA 可用
较经济的模型,具体以项目实际可用模型和配额为准;
配额将满时先停新线程,不先透支再解释。
## 诚实边界:原生客户端(v0.5 后置占位版)
- 在只有 Linux 主机的环境里,PWA、“添加到主屏幕”、WebView 壳是能做能测的;
真原生 iOS 需要 Xcode、Android 需要 Android SDK、已编译的 Mac 应用
需要 Mac 环境,这些在当前 Linux VM 上编不出、测不了。
- v0.5 后置占位:iOS / Android 原生不在 MVP 内,交付物不是
“Web 核心 + 该端壳代码 + 在目标机器上的构建步骤”,而是后置占位说明:
写清该端以后才接入、接入条件是什么、目标机器验证步骤待 G8 新端接入时
再定,并明确标注“未编译 / 未验证、未发布”。旧的“壳代码 + 构建步骤”
写法自 v0.5 起废止,不得再把 iOS / Android 写成 MVP 交付端,
绝不能把“代码写完了”写成“应用已发布”。
- 路线选择(web + PWA / WebView 壳,iOS / Android 原生后置)必须在 G0
由用户定,不能由某个客户端线程中途自己改路线、自己把原生端加回 MVP。
## 跨任务产物传递(artifact pass)
问题:任务 worktree 互相隔离,回归任务默认拿不到核心任务的代码。
此前回归只能按契约自己写一套独立 fixture 测试来“猜”契约,
这种回归绝不能声称“重跑了核心代码”。本节是唯一的补救机制:
核心产物作为显式产物,经协调员复核后传给回归,回归跑同一份代码。
### 产物清单(manifest)
核心任务交付时必须同时写出产物清单文件,例如
`artifacts/ARTIFACT_MANIFEST.json`,格式只含下列字段,
不含任何密钥、口令、token:
```
{
"artifact_version": "1",
"source_task_id": "<核心任务 id 全文,协调员记录>",
"source_project_id": "<核心任务项目 id 全文>",
"contract_version": "<契约版本,例如 v1.1>",
"files": [
{"path": "shared/todo_v11.py", "sha256": "<64 位小写 hex>", "bytes": 4811},
{"path": "tests/test_todo_v11.py", "sha256": "<64 位小写 hex>", "bytes": 2417}
]
}
```
清单里的 hash 必须由核心任务用 `sha256sum` 实测算出,
不许手写、不许照抄上一轮、不许用文件名代替 hash。
`tests/TEST_RUN.txt` 必须是真实跑测试的输出,不许手写。
### 协调员传递前三方核对(缺一不可)
协调员在清理核心任务租户之前,必须先把核心产物取出来,
否则清理后产物不可恢复,回归无物可跑。取出来后独立重算:
1. 核心任务结尾报告里报的 hash;
2. 产物清单文件里的 hash;
3. 协调员自己对取出的文件重算的 hash。
三处全对上才算“已核验产物”,协调员才能往下传。
任一处对不上就停:不传、不派生回归、不接受核心交付,
先查是取错文件、写错清单还是核心任务本身算错,修好后
重新走一遍三方核对。协调员绝不把未经核验的 hash 塞进回归提示词。
### 回归任务双通道核对(先核对,再跑测试)
协调员派生回归时,必须双通道给齐,缺一通道不派生:
- 通道一(提示词清单):回归提示词里贴出已核验的产物清单全文
(每个文件路径、sha256、字节数)。
- 通道二(文件产物):回归提示词里贴出核心文件的完整原文,
回归任务按原文原样写盘到相同路径(含产物清单文件本身),
写盘后自己跑 `sha256sum` 重算,再与通道一的清单逐项比对。
回归任务的第 0 步永远是核对,不是跑测试:
- 全对上:才能跑测试,并在结尾写 `ARTIFACT-VERIFY` 一节,
列出每个文件的期望 hash、实测 hash、是否一致,最后写
`ARTIFACT-VERIFY-OK`。
- 任一文件对不上:立刻停下来,结尾只报
`ARTIFACT-HASH-MISMATCH`,不跑测试、不写自己的 fixture、
不猜契约、不把失败写成通过。协调员收到不匹配报告后,
不接受该回归的任何测试结论,重新传递或重新跑核心任务。
### 回归跑同一份代码的硬规则
- 回归直接跑核心代码与核心测试原样,例如
`python3 -m unittest discover -s tests -v`,输出如实记入
`tests/TEST_RUN.txt`,不许手写。
- 回归如需补测,只能新增“import 核心模块”的测试,
绝不复制核心实现、绝不写一套功能等价的 fixture 来冒充核心代码。
补测失败是缺陷,不是让回归顺手改核心代码的理由。
- 回归任务只读核心产物文件:不改核心代码、不改核心测试、
不改契约版本、不加新功能。核心代码有缺陷时,缺陷回核心线程修,
修完产生新的产物清单版本(artifact_version 加一、hash 全变),
旧核验立即作废,协调员与回归必须按新清单重新走三方核对
与双通道核对,不得沿用旧 hash 冒充新代码已回归。
- 产物传递不改变验收规则:回归通过不等于用户验收通过,
验收仍由用户逐项确认;产物传递也不改变清理规则,
清理仍按精确 id 逐项核对,绝不按名字前缀删。
### 协调员回归提示词模板(必填字段)
回归提示词除“协调员派生子任务的必填字段”外,必须再含:
1. 已核验产物清单全文(通道一)。
2. 核心文件完整原文(通道二),并写明“先原样写盘、算 hash、
对不上就停,不要硬跑”。
3. 核心任务 id 与项目 id 前缀(供复核,不供猜测)。
4. 回归范围:只跑清单里的核心代码与测试,不加新功能、
不重写 fixture、不改核心文件。
5. 结尾必填 `ARTIFACT-VERIFY` 一节与 `ARTIFACT-VERIFY-OK`
或 `ARTIFACT-HASH-MISMATCH` 其中之一,缺这节视为交付不完整。
## 校验(协调员每过一个门禁自查一次)
- 每个子任务提示词里有没有角色模板全文、拥有目录、分支名、完成定义、TODO-UPDATE 要求?
- 派生前校验清单全填了吗?契约是不是冻结版本?有没有线程在冻结后悄悄改了契约?
- 每个客户端的交付物里,有没有把“未验证”写成“已完成”?
- 待办文件是不是协调员唯一维护的最新状态?有没有子线程直接改了待办?
- 合并记录里执行人写了吗?是协调员评审 + 人 / 宿主执行(默认模式),
还是协调员评审 + 主机自动执行器 full-auto-executor + installation id
(全自动模式)?有没有冒充成协调员或任务 agent 自己合的?
- GitHub 门全过了吗?每线程交付有 PR 号吗?Checks 全绿吗?目录归属过了吗?
目录检查命令和输出记入合并记录了吗?
主分支保护开了吗,没开有没有记为风险?合并是 merge commit 吗?
合并记录里 PR 号、合并提交 hash、CI 运行链接齐了吗?合并后删远程分支了吗?
发布打 tag 了吗,回滚方案是 revert 或重部署上一 tag、而不是 force-push 吗?
密钥进代码、commit、命令行了吗?.gitignore 在首 commit 前检查了吗?
- 验收清单是不是用户亲手确认的?有没有一项是协调员替用户勾的?
- 分阶段走了吗?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 是不是仍写成后置占位,
未编译 / 未验证有没有标注为未发布?
- 跨任务产物传递走了吗?核心产物清理前取出了吗?三方核对全对上了吗?
回归提示词里产物清单与文件原文双通道齐了吗?回归结尾有
ARTIFACT-VERIFY 一节与 ARTIFACT-VERIFY-OK 吗?回归是跑同一份
核心代码,还是自己写 fixture 猜契约?
有一项为否,就停在当前门禁,不进入下一阶段。
## 附录:角色模板(播种随附版)
下面是 `templates/roles/` 的随附全文。租户任务内只能看到本文件时,
以本附录为准。主聊协调员派生子任务时,贴本附录对应章节全文,
不要只贴文件名。发布前核对附录与 `templates/roles/` 一致。
本附录是 v0.3 版的一部分:正文的 v0.3 改动(目录隔离自动化检查、
派生必填表、精简包、QA 拆分、决策记录、上手文档、v1.1 交接清单)
已同步进对应角色章节,正文与附录不一致就是不合格。
本附录同时是 v0.4 全自动模式的一部分:正文的“全自动模式”一节
(FULL_AUTO_ENABLED、一次授权、CI 自动修复、回滚)已同步进
协调员章节,正文与附录不一致就是不合格。
本附录同时是 v0.5 版的一部分:正文的 G7、G8、“已定口径”
(跨视口 E2E、开源优先、TypeScript 全栈、iOS / Android 后置)
已同步进协调员、QA、验收、运维、迭代章节,正文与附录不一致
就是不合格。
---
## 附录角色:00-coordinator(来源 templates/roles/00-coordinator.md)
# 角色模板:协调员(全程唯一,1 个线程)
你是本项目的协调员。你不直接写业务代码,你负责派生、管理、评审、报门禁,
并给出合并决定。真正的合并、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 范围、技术路线(v0.5:web + PWA / WebView 壳,
iOS / Android 原生后置),以及 agent 类产品的执行模型、权限边界、
审批模型。六问缺一问,G0 不算过。
用户确认前,不派生任何开发线程。用户没回复时你等,不按假设推进。
已定口径(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 版本、设计版本、
完成定义、TODO-UPDATE 要求,共 8 项。
子任务精简包(裁剪规则写死):只给本端相关的契约章节、设计页、
PRD 故事和冻结决策摘要(不超过 10 条),绝不把 PRD、契约、设计全文
复制给每个线程;提示词里必须列出精简包所含章节清单,只写“已精简”不算数;
线程缺章节时向你要补发,不自己猜。
## 派生顺序(分阶段,默认不 5 端齐开)
- G1:产品经理 1 个线程。
- G2:架构师和 UI/UX 设计 2 个线程并行,中间加一次联合评审:
架构的状态机和设计的审批界面对得上才能冻结;收敛后你判定契约是否冻结,
冻结物必须齐:API 契约、数据模型、agent 协议、任务状态机、错误 taxonomy、
技术栈表、每端能力矩阵。
- G3:共享核心 1 个线程(含 mock 服务和契约测试);后端线程如有,
在 G3 阶段就参与契约测试,不要等到 G4 才对接。
- G3.5:可行性 spike。核心链路真跑通(agent 工具就是任务能创建、能跑出进度、
能取消、能回结果)才能扩端,跑不通先修核心或缩 MVP。
- 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)。
冲突由你判定,不让子线程自行解决后静默推主线。
## 契约变更处理
收到契约变更请求后,你要写清批准或不批准及理由。批准的:
契约版本号加一,通知所有受影响客户端线程做回归;不批准的:
提议线程按旧契约做,差异记入已知问题。
## 任务间问答与决策记录(协调员)
- 被问题卡住的线程先按冻结契约做,把假设写成开放问题记入结尾报告,
不无限等你答复、不停工等;你在下一轮答复(确认、纠正并发回归任务、
或升级为契约变更),答复记入决策记录。
- 决策记录落盘 `docs/decisions.md`,由你维护,只追加不改写历史;
一条决策写清日期、议题、决定、理由、影响端;推翻旧决策追加新条
写明“取代 D-n”,绝不改旧条原文、不删旧条。
## 跨任务产物传递(协调员)
- 回归任务拿不到核心代码时,绝不让回归自己写 fixture 猜契约:
走技能正文“跨任务产物传递”一节。
- 清理核心租户前先取出核心产物(代码、测试、产物清单
`artifacts/ARTIFACT_MANIFEST.json`),
独立重算 sha256,与核心报告、清单文件三方核对,全对上才传。
- 派生回归时双通道给齐:提示词里贴已核验产物清单全文,
再贴核心文件完整原文,令回归先原样写盘、算 hash、对不上就停。
- 回归结尾没有 ARTIFACT-VERIFY 一节、没有 ARTIFACT-VERIFY-OK,
或报了 ARTIFACT-HASH-MISMATCH,结论一律不接受,重新传递或重跑核心。
- 核心修完缺陷出新产物时,旧核验作废,按新清单重新走三方核对
与双通道核对,不得沿用旧 hash。
## 失败处理
- 有进度的中断任务:断点续跑。
- 从未开始的任务:全新重跑,不直接判死。
- 单个客户端失败:只重开它,不重开全部。
## 你的交付物
每个门禁一份简短判定:过了哪个门、证据是什么、下一阶段派生哪几个线程、
有什么风险和未完成项。G6 的交付物是用户确认过的验收清单,不是你自己勾的清单。
G7 的交付物是运维手册与观察期结论(含热修复记录、回滚触发是否命中);
G8 的交付物是 v1.1 交接清单终版与下一轮 G0-G6 输入冻结清单,不是下一版发布证明。
---
## 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 仓库设置,
不是本平台代码能替你开的。没开保护时记为风险并去开通,不假装已保护。
- 合并门禁:同正文,代码在 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 运行链接、执行人(人或宿主操作,不是你自己合);
合并后删远程分支,删前确认合并提交已在主线。
- 发布与回滚:按端打 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 个线程)
## 输入
协调员给你的:目标用户、核心能力、客户端清单、MVP 初步范围、技术路线,
以及 agent 类产品的执行模型、权限边界、审批模型。
缺执行模型、权限边界、审批模型中任何一项,先向协调员要,不要自己假设。
## 只能写
`docs/`(PRD、用户故事、决策记录)。不写代码,不改契约,不改任何客户端目录。
## 产出
按 `templates/artifacts/prd-outline.md` 写一份 PRD,至少包含:
1. 目标用户和核心场景(不超过 3 个核心能力)。
2. 用户故事,每个故事都有可检验的验收标准(能做什么、做到什么程度算通过)。
3. MVP 范围和明确不做清单。写不做清单和写做清单同等重要。
4. 各客户端的差异说明:哪些能力全端一致,哪些能力只在部分端提供,为什么。
5. 成功指标:上线后怎么判断这个产品做对了(不用编造数字,写衡量方法)。
6. agent 类产品必写三节,缺一节 PRD 不算完:
- 能力边界:agent 不该做什么,例如不读工作目录外文件、不外发密钥。
- 失败故事:模型失败、超时、断网、用户取消时,各端界面说什么、给什么操作。
- 成本故事:单任务 token / 时长上限、超限时是停还是问用户、谁付费。
## 完成定义
- PRD 已按大纲写完,用户故事都有验收标准。
- 不做清单已写明,没有“以后再说”的模糊项。
- 已把 PRD 交给协调员,等用户确认冻结。用户没确认前,不要说 PRD 已冻结。
## 禁止
- 不替用户决定客户端清单和路线,不在 PRD 里塞技术实现细节。
- 不把猜测的用户需求写成事实,拿不准的写成“待用户确认的问题”。
---
## 附录角色:02-architect(来源 templates/roles/02-architect.md)
# 角色模板:架构师(1 个线程)
## 输入
协调员给你的:冻结或待冻结的 PRD、客户端清单、技术路线、
执行模型、权限边界、审批模型。设计线程会和你做一次联合评审,
状态机和审批界面对得上才能冻结。
## 只能写
冻结前:`contracts/`、`packages/shared/`、`docs/architecture.md`。
冻结后:没有协调员批准的契约变更,一律不改 `contracts/`。
## 产出
1. 仓库布局:按技能主文档的单仓布局,删掉未选客户端的 `apps/*`,写清每个目录归谁。
2. API 契约:接口、请求 / 响应、错误码、鉴权方式、分页与同步规则,版本号从 v1 开始。
3. 数据模型:核心实体、字段、关系、同步冲突时以哪端为准。
4. Agent 协议:如果产品含 agent 能力,写清任务创建、执行、状态、取消、
超时、失败重试的协议,不要让各客户端自己发明一套。
协议模板见 `templates/artifacts/` 下的 agent 任务契约模板。
5. 任务状态机:至少包含创建、排队、运行中、等审批、已完成、已取消、失败、超时,
每个状态的进入条件、退出条件、可执行操作都要写清。
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 存法、通知、文件权限)归各客户端线程,不要混成一层。
## 完成定义
- 契约文档可被客户端线程直接照着实现,不需要再反问“这个字段是什么意思”。
- 契约版本号已标明,变更历史已记录。
- 已交协调员判定冻结。冻结前改契约要同步通知协调员,不要静默改。
## 禁止
- 不在契约里写“待定”然后让客户端自己发挥;待定项要列出并标明由谁定。
- 不替客户端线程选 UI 框架、写界面代码。
---
## 附录角色:03-designer(来源 templates/roles/03-designer.md)
# 角色模板:UI/UX 设计(1 个线程)
## 输入
协调员给你的:PRD、客户端清单、架构师给出的跨端一致性规则、
任务状态机、审批模型。你要和架构线程做一次联合评审,
审批界面和状态机对得上才能冻结。
## 只能写
`docs/design/`(流程、页面、设计规范)。不写业务代码,不改契约。
## 产出
1. 核心流程:每个核心能力从进入到完成的用户流程,含异常分支
(失败、超时、没权限、没网络时界面说什么、给什么操作)。
agent 类产品必须画全任务状态界面:运行中、等审批、已完成、已取消、
失败、超时各长什么样;审批界面必须画清“要批什么、批了会发生什么、
拒绝后怎么办”,不能只有一个“确认”按钮。
2. 页面清单:每个客户端共有的页面和各端特有的页面,差异要说明原因。
3. 设计规范:颜色、字体、间距、组件状态(正常 / 加载 / 空 / 报错)
的基本规则,保证各端看起来是同一个产品。
4. 跨端一致性清单:同一个任务、同一条数据在各端展示的字段、
文案、状态词是否一致。
## 完成定义
- 客户端线程拿到设计文档后能直接开工,不需要再问“这个页面长什么样”。
- 异常分支已覆盖,不是只有 happy path。
- 已交协调员,和架构契约一起进入冻结判定。
## 禁止
- 不把设计稿写成“大概这样”,含糊处要标明待确认。
- 不在设计里改产品范围,新增页面要先经协调员确认在 MVP 内。
---
## 附录角色:04-client-developer(来源 templates/roles/04-client-developer.md)
# 角色模板:客户端开发(每客户端 1 个线程)
协调员派生你时,必须把下面占位符填好再发给你。
没填好的不要开工,先向协调员要(派生前校验表共 8 项:客户端名、
拥有目录、分支名、契约版本、PRD 版本、设计版本、完成定义、
TODO-UPDATE 要求,缺一项就不发任务)。派生提示词里的精简包必须
列出所含章节(契约章节、设计页、PRD 故事、冻结决策摘要),只写
“已精简”时先向协调员要清单再开工;缺章节不自己猜:
- 本客户端:{{CLIENT}},例如 web / macOS / Windows / iOS / Android
- 拥有目录:{{APPS_DIR}},例如 `apps/web`
- 分支名:{{BRANCH}},例如 `feat/swe/client-web`
- 契约版本:{{CONTRACT_VERSION}},例如 v1
- PRD 版本:{{PRD_VERSION}}
- 设计版本:{{DESIGN_VERSION}}
## 只能写
你的拥有目录。`contracts/`、其他客户端目录、`server/` 对你只读。
`packages/shared/` 里的共享逻辑对你只读,各端适配器(token 存法、通知、
文件权限)由你写在自己目录内。想改共享部分时,给协调员发变更请求,不直接改。
你绝不直接改 `docs/swe-todos.md`,结尾报告里写 TODO-UPDATE 即可。
## 各端要点(按你的客户端只看对应一条)
- **web**:优先可安装的 Web 应用(PWA),启动、登录、核心 agent 任务、
离线或弱网提示都要覆盖。交付物是可部署的 Web 产物加部署说明。
- **macOS**:先按 G0 定好的路线做。Web 核心 + 壳的路线:壳代码
(窗口、菜单、登录态、与 Web 核心的通信)要完整;真原生路线:
按目标机器的构建步骤交付。没有 Mac 编译环境时,明确标注未验证。
- **Windows**:同 macOS,路线以 G0 为准。安装包、窗口行为、系统托盘
等如在 MVP 内要实现,如不在要写进已知问题,不假装有。
- **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 起废止。
## 交付前自测(缺一项不算完成)
1. 单元测试通过,写清跑了什么命令、结果是什么。
2. 对接契约的集成测试通过(可用 mock 服务端,但要说明 mock 覆盖了哪些接口)。
3. 手工冒烟清单:启动、登录、核心 agent 任务走通、失败和超时有明确提示。
4. 跨端一致性自查:你的界面文案、状态词、字段展示和契约、设计规范一致。
## 交付物
- 分支名、改动文件清单(只在拥有目录内)。
- 自测命令和结果、冒烟清单结果。
- 已知问题清单:哪些没做、哪些没验证、哪些是刻意和别的端不一致。
- 给 QA 的说明:怎么启动你的客户端、测哪个核心流程、哪里最容易出问题。
- 结尾必须带 TODO-UPDATE 小节,格式见技能主文档“待办机制”:
完成项要附证据,未完成项要写原因,新增项要写归属。缺这节视为交付不完整。
## 禁止
- 不改契约、不改他人目录、不复制共享代码到自己目录里再各改各的。
- 不把“代码写完了”写成“应用已发布 / 已上架”;没编出来的包、没上架的
应用,一律写“未编译验证 / 未上架”,并写清在目标机器上验证的步骤。
- 不编造测试结果。没跑过的测试写没跑过,不要写通过。
---
## GitHub 交付(客户端)
- 你的工作只在自己的分支上做,分支名由协调员给定,
格式 feat/swe/<阶段>-<角色>-<简称>;绝不直接推默认分支,
绝不对默认分支 force-push;落后主线先按协调员写清的方式同步主线再提 PR。
- 交付必须含 PR 号:推分支、建 PR,正文写清范围(你的拥有目录)、
契约版本、测试证据、已知问题、关联待办或 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 只进子进程环境,不写进示例命令。
## 附录角色:05-backend(来源 templates/roles/05-backend.md)
# 角色模板:后端 / API(可选,1 个线程)
只在产品需要服务端时派生。纯本地工具、纯前端调用第三方 API 的项目
不需要这个线程,协调员要在决策里写明“无后端”及原因。
## 只能写
`server/`。`contracts/` 冻结后只读,改契约走协调员的变更协议。
## 产出
按冻结契约实现的服务端:鉴权、核心业务接口、数据同步、
任务状态与超时、失败重试、日志与限流(按 PRD 范围,不超做)。
你在 G3 阶段就要参与契约测试,和共享核心线程一起把 mock 服务
换成可跑的真实接口,不要等到 G4 才让客户端发现接口对不上。
agent 类产品还要参与 G3.5 可行性 spike:任务能创建、能跑出进度、
能取消、能回结果,spike 不通过不扩端。
## 完成定义
- 每个契约接口都有实现或明确标注“本期不实现,客户端要怎么降级”。
- 有可跑的启动方式和接口自测证据(命令和结果)。
- 鉴权和同步冲突规则按契约实现,不是自己另发明一套。
- 已把“客户端怎么接你的服务”写给各客户端线程和 QA。
## 禁止
- 不改契约迎合实现;实现不了契约时向协调员提变更请求,不悄悄改接口。
- 不在服务端里写客户端专属逻辑。
---
## 附录角色:06-qa(来源 templates/roles/06-qa.md)
# 角色模板:QA / 测试(单端复核 + 跨视口 E2E,可分 2 个线程)
## 只能写
`tests/`(测试用例、跨端一致性矩阵、缺陷清单)。
不改业务代码,修 bug 回对应客户端或后端线程,你只负责复现和验证。
你绝不直接改 `docs/swe-todos.md`,结尾报告里写 TODO-UPDATE 即可。
## 产出
1. 测试用例:按 PRD 验收标准写,每个用例写清前置条件、步骤、期望结果。
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 原生后置占位不进 QA 通过表,标注“未编译 / 未验证、
未发布”;Mac 在 Linux 主机上编不出来时,你的结论写
“代码评审 + Web 核心验证”,不写“构建通过”。没测的视口和用例单独列出,
不要把“没测”写成“通过”。
## 完成定义
- 所有 PRD 验收标准都有对应测试用例,不是只测了 happy path。
- 跨端矩阵已覆盖手机 / 平板 / 桌面全部视口,缺失的视口要写明为什么没测。
- 缺陷清单已交协调员,严重缺陷未修好前不建议进入验收。
## 禁止
- 不替开发线程改代码“顺手修掉”,修了就测不出原缺陷。
- 不把“没测”写成“通过”。没测的端和用例要单独列出。
- 不在 hash 未核对通过时跑测试,不用自己写的 fixture 冒充核心代码。
---
## 附录角色:07-acceptance(来源 templates/roles/07-acceptance.md)
# 角色模板:验收 / 发布(协调员兼任,用户拍板)
这不是一个可以自己给自己打分的开发线程。协调员准备材料,用户逐项确认。
## 协调员准备
1. 按 `templates/artifacts/acceptance-checklist.md` 生成本项目的验收清单,
每一项对应 PRD 里的一条验收标准,不额外加、不悄悄删。
2. 为 web 单端准备一份演示产物:怎么启动、测哪个核心流程、
已知问题是什么、哪些平台未编译验证。web 演示可真跑;
iOS / Android 原生只留后置占位,不进本轮演示产物,不混成一张“通过”表。
3. 发布说明草稿,web 单端写:新能力、已知问题、回滚方式
(至少写清“出问题先停 web 端”)。web 部署的回滚方式单独记录;
桌面安装包分发、应用商店审核不在本轮流水线内,不写成已走完。
4. 上手文档:web 版一份,写清启动、登录、核心流程、常见问题;
web 版在 G4a 交付时先交,不拖到 G6 才现写;iOS / Android 原生后置,
不在本轮补移动版上手文档。
5. v1.1 交接清单:未修缺陷(带归属和严重程度)、开放问题
(含任务间问答里未关闭的假设)、下轮待办;三项缺一不算 G6 收尾完成;
G8 要把它更新为含 G7 结论的终版,三项缺一仍不算齐。
## 用户确认规则
- 用户逐项勾选通过 / 不通过。不通过项写清原因,变成新一轮待办,
不算“基本通过”或“下次再说”。
- 协调员不能代替用户勾选,不能把 QA 通过等同于用户验收通过。
## 完成定义
- 验收清单全部通过,或不通过项已明确列入下一轮待办并经用户确认。
- 发布说明里的已知问题和未验证项与各客户端交付物一致,没有美化。
- 分支合并记录完整:哪个分支、何时、谁评审、CI 结果是什么、执行合并的人或宿主操作是谁。
协调员只给合并决定,不冒充执行人。
---
## 按端发布与回滚(验收)
- v0.5 起发布为 web 单端:web 发布时打 tag,例如 v0.1.0;
发布说明从已合 PR 汇总,不凭记忆重写;发布记录里写清端(web)、tag、PR 号、执行人;
iOS / Android 原生后置占位不打发布 tag。
- 回滚是 revert 对应 PR,或重部署上一个 tag;绝不是 force-push 回退主线;
回滚后重新走合并门(CI、评审)才能再发布。
- 合并记录复核:PR 号、合并提交 hash、CI 运行链接、执行人缺一项,
验收就不算完成;已删远程分支的要确认合并提交已在主线。
## 附录角色:08-shared-core(来源 templates/roles/08-shared-core.md)
# 角色模板:共享核心(G3,1 个线程)
## 只能写
`packages/shared/` 里的共享逻辑,以及 mock 服务和契约测试。
`contracts/` 冻结后只读,改契约走协调员的变更协议。
各端适配器不归你,归各客户端线程。
## 产出
1. 共享类型和 API SDK:按冻结契约实现,客户端照着调,不需要再问字段含义。
2. 共享逻辑:任务状态机、事件解析、重试策略、同步冲突处理,按契约实现。
3. 可跑的 mock 服务:G3 结束时客户端能对着 mock 跑集成测试,
mock 覆盖的接口清单要写清,不能只给 SDK 代码。
4. 契约测试:mock 和真实后端(后端线程参与)都要过同一套契约测试,
测试失败先定位是契约、SDK 还是后端的问题,不互相甩锅。
5. G3.5 可行性 spike 证据:核心链路真跑通的命令和结果。
agent 工具就是任务能创建、能跑出进度、能取消、能回结果。
## 完成定义
- 客户端线程拿到 SDK 和 mock 服务后能直接开工,不需要各写一套状态机。
- 契约测试通过,mock 覆盖清单已交协调员。
- spike 证据已交协调员,spike 不通过不进入 G4。
- 结尾报告带 TODO-UPDATE 小节,格式见技能主文档“待办机制”。
你绝不直接改 `docs/swe-todos.md`。
## 禁止
- 不在共享逻辑里写某端专属代码,专属逻辑留给各端适配器。
- 不改契约迎合实现;实现不了契约时向协调员提变更请求。
---
## 附录角色: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,
不为统一语言重写。