name: 撰写设计计划 description: 在头脑风暴完成后使用 - 将验证后的设计写入docs/design-plans/,采用结构化格式和离散的实现阶段,用于创建详细的实施计划 user-invocable: false
撰写设计计划
概述
通过将已验证的设计从头脑风暴附加到现有文件(在启动设计计划的第3阶段创建)并填充摘要和词汇表占位符来完成设计文档。
核心原则: 将正文附加到现有文档。生成摘要和词汇表。提交以实现永久性。
开始时宣布: “我正在使用撰写设计计划技能来完成设计文档。”
上下文: 设计文档已存在,包含标题、摘要占位符、确认的完成定义和词汇表占位符。此技能附加正文并填充占位符。
详细程度:设计与实施
设计计划是方向性和存档性的。 它们可以提交到git并数月后参考。其他设计计划可能依赖于此处指定的契约。
实施计划是战术性和即时性的。 它们验证当前代码库状态,并在执行前立即生成可执行代码。
设计计划中应包含的内容:
| 包含 | 排除 |
|---|---|
| 模块和目录结构 | 任务级分解 |
| 组件名称和职责 | 实施代码 |
| 文件路径(来自调查) | 函数体 |
| 组件间的依赖关系 | 逐步说明 |
| “完成时”验证标准 | 测试代码 |
例外:契约需完整指定。 当组件暴露其他系统依赖的接口时,完整指定契约:
- API端点,包含请求/响应形状
- 服务间接口(类型、方法签名)
- 其他系统读取的数据库模式
- 队列/事件的消息格式
契约可以包括显示类型和接口的代码块。这与实施代码不同——契约定义边界,而非行为。
示例——契约规范(可接受):
interface TokenService {
generate(claims: TokenClaims): Promise<string>;
validate(token: string): Promise<TokenClaims | null>;
}
interface TokenClaims {
sub: string; // 服务标识符
aud: string[]; // 允许的受众
exp: number; // 过期时间戳
}
示例——实施代码(设计计划中不可接受):
async function generate(claims: TokenClaims): Promise<string> {
const payload = { ...claims, iat: Date.now() };
return jwt.sign(payload, config.secret, { algorithm: 'RS256' });
}
第一个定义边界的外观。第二个实现行为——这属于实施计划。
文件位置和命名
文件位置: docs/design-plans/YYYY-MM-DD-<主题>.md
文件由启动设计计划的第3阶段创建。此技能附加到该文件。
预期命名约定:
- 良好:
docs/design-plans/2025-01-18-oauth2-svc-authn.md - 良好:
docs/design-plans/2025-01-18-user-prof-redesign.md - 不良:
docs/design-plans/design.md - 不良:
docs/design-plans/new-feature.md
文档结构
设计文档已存在,来自启动设计计划的第3阶段,结构如下:
# [功能名称] 设计
## 摘要
<!-- 正文写入后生成 -->
## 完成定义
[已编写 - 在第3阶段确认]
## 验收标准
<!-- 生成并在词汇表前验证 -->
## 词汇表
<!-- 正文写入后生成 -->
此技能附加正文部分:
## 架构
[在头脑风暴第2阶段选择的方法]
[关键组件及其交互方式]
[数据流和系统边界]
## 现有模式
[记录调查发现的代码库模式,本设计遵循这些模式]
[如果引入新模式,解释原因并注意与现有代码的差异]
[如果未找到现有模式,明确说明]
## 实施阶段
将实施分解为离散阶段(建议<=8个)。
**必需:用HTML注释标记包裹每个阶段:**
<!-- START_PHASE_1 -->
### 阶段 1: [名称]
**目标:** 此阶段实现的内容
**组件:** 构建/修改的内容(来自调查的确切路径)
**依赖关系:** 必须先存在的内容
**完成时:** 如何验证此阶段完成(见阶段验证部分)
<!-- END_PHASE_1 -->
<!-- START_PHASE_2 -->
### 阶段 2: [名称]
[相同结构]
<!-- END_PHASE_2 -->
...为每个阶段继续...
**为什么使用标记:** 这些使撰写实施计划能够单独解析阶段,减少上下文使用,并支持跨压缩边界的细粒度任务跟踪。
## 额外考虑
[错误处理、边缘情况、未来可扩展性 - 仅在相关时]
[不包括假设的“锦上添花”功能]
然后此技能:
- 生成验收标准(内联)并获取人工验证
- 生成摘要和词汇表以替换占位符
可读性头部
前三部分(摘要、完成定义、词汇表)构成可读性头部。这些部分帮助人工评审者在深入技术细节前快速理解文档内容。
完成定义已编写——它在第3阶段用户确认后立即捕获,保持完整保真度。
摘要和词汇表在写入正文后生成。这避免了总结尚未编写的内容,并确保它们准确反映完整文档。
见下方“写入后:生成摘要和词汇表”以获取提取过程。
实施阶段:关键要求
您必须将设计分解为离散、顺序的阶段。
每个阶段应:
- 实现一个连贯目标
- 基于先前阶段(明确依赖关系)
- 以工作构建和清晰的“完成”标准结束
- 使用来自代码库调查的确切文件路径和组件名称
阶段验证
验证取决于阶段交付的内容:
| 阶段类型 | 完成时 | 示例 |
|---|---|---|
| 基础设施/脚手架 | 操作成功 | 项目安装、构建、运行、部署 |
| 功能/行为 | 通过验证此阶段覆盖的AC的测试 | 单元测试、集成测试、端到端测试 |
规则: 如果一个阶段实现功能,它必须包括验证其声称覆盖的特定验收标准的测试。测试是阶段的交付物,而不是后续的单独“测试阶段”。
将测试与AC绑定: 功能阶段列出它覆盖的AC(例如,oauth2-svc-authn.AC1.1,oauth2-svc-authn.AC1.3)。阶段在存在验证每个特定案例的测试之前不“完成”。这创建了可追溯性:AC → 阶段 → 测试。
不要过度工程化基础设施验证。 您不需要对package.json进行单元测试。“npm install 成功”足以验证依赖设置阶段。基础设施阶段通常不列出AC——它们的验证是操作性的。
确实需要功能测试。 任何执行操作的代码都需要证明其执行该操作的测试。这些测试必须映射到特定AC,而不仅仅是“测试代码”。如果一个阶段覆盖oauth2-svc-authn.AC1.3(“无效密码返回401”),测试必须准确验证这一点。
测试可以演进。 在阶段2编写的测试可能在阶段4随着需求扩展而修改。这是预期的。约束是阶段2以通过阶段2声称覆盖的AC的测试结束。
将阶段结构化为子组件。 一个阶段可能包含多个逻辑子组件。在组件级别列出它们——实施计划将把这些分解为任务。
良好结构(组件级别):
<!-- START_PHASE_2 -->
### 阶段 2: 核心服务
**目标:** 令牌生成和会话管理
**组件:**
- `src/services/auth/`中的TokenService — 生成和验证JWT令牌
- `src/services/auth/`中的SessionManager — 创建、验证和使会话无效
- `src/types/auth.ts`中的类型 — TokenClaims、SessionData接口
**依赖关系:** 阶段1(项目设置)
**完成时:** 令牌生成/验证工作,会话可以创建/使无效,所有测试通过
<!-- END_PHASE_2 -->
不良结构(任务级别——这属于实施计划):
阶段 2: 核心服务
- 任务 1: TokenPayload类型和TokenConfig
- 任务 2: TokenService实施
- 任务 3: TokenService测试
- 任务 4: SessionManager实施
- 任务 5: SessionManager测试
设计计划描述构建什么。实施计划描述如何逐步构建它。
阶段数量:
- 目标:5-8个阶段(规划的甜蜜点)
- 最大:8个阶段(撰写计划技能硬限制)
- 如果需要>8个阶段:注意将需要多个实施计划
为什么<=8个阶段重要:
- 撰写计划技能每个实施计划有8个阶段的硬限制
- 超过8个阶段强制用户调整范围或拆分
- 这是设计以防止实施计划不堪重负
如果设计需要>8个阶段:
添加注释到额外考虑:
## 额外考虑
**实施范围调整:** 此设计共有[N]个阶段。撰写计划技能限制实施计划为8个阶段。考虑:
1. 在初始计划中实施前8个阶段
2. 为剩余阶段创建第二个实施计划
3. 简化设计以适应8个阶段内
使用代码库调查结果
包括来自调查的路径和组件描述。不包括实施细节。
良好阶段定义示例:
基础设施阶段示例:
<!-- START_PHASE_1 -->
### 阶段 1: 项目设置
**目标:** 初始化项目结构和依赖项
**组件:**
- 带有auth依赖项的`package.json`(jsonwebtoken, bcrypt)
- 带有严格模式的`tsconfig.json`
- 入口点`src/index.ts`
**依赖关系:** 无(第一阶段)
**完成时:** `npm install`成功,`npm run build`成功
<!-- END_PHASE_1 -->
功能阶段示例:
<!-- START_PHASE_2 -->
### 阶段 2: 令牌生成服务
**目标:** 用于服务间认证的JWT令牌生成和验证
**组件:**
- `src/services/auth/`中的TokenService — 生成签名的JWT,验证签名和过期
- `src/services/auth/`中的TokenValidator — 中间件友好的验证,返回声明或拒绝
**依赖关系:** 阶段1(项目设置)
**完成时:** 令牌可以生成、验证,并在无效/过期时被拒绝
<!-- END_PHASE_2 -->
不良阶段定义示例:
太模糊:
### 阶段 1: 认证
**目标:** 添加认证内容
**组件:** 认证文件
**依赖关系:** 可能数据库
太详细(任务级别):
### 阶段 2: 令牌服务
**组件:**
- 创建`src/types/token.ts`包含TokenClaims接口
- 创建`src/services/auth/token-service.ts`包含generate()和validate()
- 创建`tests/services/auth/token-service.test.ts`
- 步骤 1: 为generate()编写失败测试
- 步骤 2: 实施generate()
- 步骤 3: 为validate()编写失败测试
...
第二个示例在执行实施计划的工作。设计计划保持在组件级别。
写作风格
必需子技能: 如果可用,使用house-style:writing-for-a-technical-audience。
否则遵循这些指南:
简洁:
- 移除开场白
- 直接陈述事实
- 跳过明显解释
具体:
- 使用确切组件名称
- 引用实际文件路径
- 包括具体示例
诚实:
- 承认未知
- 明确说明假设
- 不要过度承诺
示例 - 良好:
## 架构
使用OAuth2客户端凭证流的服务间认证。
认证服务(`src/services/auth/`)生成和验证JWT令牌。API中间件(`src/api/middleware/auth.ts`)验证传入请求的令牌。令牌存储(`src/data/token-store.ts`)在PostgreSQL中维护吊销列表。
令牌1小时后过期。服务账户不需要刷新(可以请求新令牌)。
示例 - 不良:
## 架构
在这个激动人心的新架构中,我们将实施一个健壮且可扩展的认证系统,利用OAuth2的力量!系统将按照最佳实践设计,确保每个级别的安全性和性能。我们将使用行业标准的JWT令牌,提供出色的灵活性,并在整个生态系统中广泛支持。这将与我们现有的基础设施无缝集成,并为未来增强提供坚实基础!
现有模式部分
目的: 记录代码库调查揭示的内容。
包括:
- 本设计遵循的现有代码模式
- 选择这些模式的原因(如果已知)
- 与现有模式的任何差异及理由
如果遵循现有模式:
## 现有模式
调查在`src/services/legacy-auth/`中找到现有认证。本设计遵循相同的服务结构:
- 服务类在`src/services/<领域>/`
- 中间件在`src/api/middleware/`
- 数据访问在`src/data/`
令牌存储遵循`src/data/session-store.ts`的模式(PostgreSQL with TTL)。
如果无现有模式:
## 现有模式
调查未找到现有认证实施。本设计引入新模式:
- 业务逻辑的服务层(`src/services/`)
- 请求拦截的中间件(`src/api/middleware/`)
这些模式与功能核心、命令式外壳分离对齐。
如果与现有模式差异:
## 现有模式
调查在`src/auth/`中找到旧版认证。本设计差异:
- 旧:整体式`src/auth/auth.js`(600行,混合关注点)
- 新:遵循FCIS的单独服务(`token-service.ts`,`validator.ts`)
差异理由:旧代码违反FCIS模式,难以测试,高耦合。
额外考虑
仅在真正相关时包括:
错误处理 - 如果不明显:
## 额外考虑
**错误处理:** 令牌验证失败返回401并带通用消息(不泄露令牌细节)。服务间通信失败在返回503前重试3次,带指数退避。
边缘情况 - 如果不明显:
**边缘情况:** 时钟偏移通过5分钟令牌验证窗口处理。吊销令牌在数据库中保留7天以供审计跟踪。
未来可扩展性 - 如果架构决策支持未来功能:
**未来可扩展性:** 令牌声明结构支持添加用户元数据(当前未使用)。启用未来人类用户认证而无需架构更改。
不包括:
- 当前设计中未包含的“锦上添花”功能
- 假设的未来需求
- 通用陈词滥调(“应安全”,“需要良好测试”)
写入正文后:生成和验证验收标准
附加正文后,生成验收标准并在摘要/词汇表前获取人工验证。
验收标准将完成定义转化为具体、可验证的项,成为实施期间测试要求的基础。您刚刚编写阶段后有完整上下文——内联执行此操作,无需子代理。
验收标准必须覆盖的内容
针对每个完成定义项,思考:
-
成功案例: 所有成功方式是什么?分别列出每个。
- 快乐路径:正常、预期流程
- 变体:不同有效输入、配置、用户类型
- 边缘情况:边界值、空输入、最大尺寸
-
重要失败案例: 系统应拒绝或优雅处理什么?
- 无效输入(格式错误、超出范围、错误类型)
- 未授权访问尝试
- 资源耗尽或不可用
- 并发访问冲突
然后查看实施阶段和头脑风暴细节以获取额外案例:
- 阶段间的集成点(数据在组件间正确流动)
- 架构决策暗示的行为(缓存、重试、超时)
- 设计讨论中浮现的边缘情况
编写标准
每个标准必须是可观察和可测试的:
良好: “API在令牌过期时返回401” 良好: “用户在密码少于8个字符时看到错误消息” 良好: “系统在2秒内处理100个并发请求”
不良: “系统安全”(模糊) 不良: “代码干净”(主观) 不良: “性能可接受”(不可测量)
结构
范围化AC格式: {slug}.AC{N}.{M},其中{slug}从设计计划文件名中提取(YYYY-MM-DD-之后的所有内容,排除.md)。
对于设计计划2025-01-18-oauth2-svc-authn.md,slug是oauth2-svc-authn。所有AC标识符使用此前缀:
## 验收标准
### oauth2-svc-authn.AC1: 用户可以认证
- **oauth2-svc-authn.AC1.1 成功:** 具有有效凭据的用户收到认证令牌
- **oauth2-svc-authn.AC1.2 成功:** 令牌包含正确的用户ID和权限
- **oauth2-svc-authn.AC1.3 失败:** 无效密码返回401,带通用错误(无密码提示)
- **oauth2-svc-authn.AC1.4 失败:** 锁定账户返回403,带锁定持续时间
- **oauth2-svc-authn.AC1.5 边缘:** 空密码字段在提交前显示验证错误
### oauth2-svc-authn.AC2: 会话跨页面刷新持久化
- **oauth2-svc-authn.AC2.1 成功:** ...
- **oauth2-svc-authn.AC2.2 失败:** ...
...
### oauth2-svc-authn.AC[N]: 横切行为
- **oauth2-svc-authn.AC[N].1:** 令牌过期触发重新认证提示(不是静默失败)
- **oauth2-svc-authn.AC[N].2:** 所有API错误包含用于调试的关联ID
- ...
为什么范围化: 多个计划与执行轮次在同一代码库中积累测试。范围化标识符防止冲突——oauth2-svc-authn.AC2.1和user-prof.AC2.1是明确的。实施阶段、任务规范和测试名称都使用完整范围化标识符。
验证
向用户呈现生成的标准。使用AskUserQuestion:“评审验收标准。批准以继续,或描述缺少或需要修订的内容。”
循环直到批准。然后替换文档中的占位符并继续到摘要/词汇表。
写入后:生成摘要和词汇表
附加正文(架构到额外考虑)后,使用具有新鲜上下文的子代理生成摘要和词汇表。
为什么使用子代理?
- 新鲜上下文避免长头脑风暴/写入会话的“上下文腐化”
- 作为强制功能:如果子代理无法提取连贯摘要,文档不清晰
- 模拟人类评审者首次看到文档的体验
步骤 1: 此时文档看起来像:
正文已附加且验收标准已验证:
# [功能名称] 设计
## 摘要
<!-- 正文写入后生成 -->
## 完成定义
[已从第3阶段编写]
## 验收标准
[在先前步骤验证]
## 词汇表
<!-- 正文写入后生成 -->
## 架构
[... 正文内容 ...]
## 现有模式
[... 正文内容 ...]
## 实施阶段
[... 正文内容 ...]
## 额外考虑
[... 正文内容 ...]
步骤 2: 派遣提取子代理
使用Task工具生成摘要和词汇表:
<invoke name="Task">
<parameter name="subagent_type">ed3d-basic-agents:sonnet-general-purpose</parameter>
<parameter name="description">为设计文档生成摘要和词汇表</parameter>
<parameter name="prompt">
阅读位于[文件路径]的设计文档。
生成两个部分以替换文档中的占位符:
1. **摘要:** 编写1-2段总结正在构建的内容和高级方法。这应使不熟悉代码库的人理解。完成定义部分已存在——您的摘要应通过解释“如何”而非重述“什么”来补充它。
2. **词汇表:** 列出应用程序中的领域术语和第三方概念(库、框架、模式),评审者需要理解这些以理解本文档。格式为:
- **[术语]:** [简要解释]
仅包括出现在文档中且会受益于解释的术语。
3. **省略术语:** 列出您考虑但跳过为太明显或通用的术语。仅包括边界情况——不太技术评审者可能不知道的术语。格式为简单逗号分隔列表。
返回所有三个部分。前两个准备插入markdown;第三个用于透明度关于省略内容。
</parameter>
</invoke>
步骤 3: 与用户评审省略术语
在插入提取部分前,简要向用户提及省略术语:
“词汇表包括[X术语]。省略为可能明显:[来自子代理的列表]。请告诉我其中任何应包含。”
不要等待批准——继续插入部分。用户可以按退出并请求调整如果需要。
步骤 4: 替换占位符
用子代理的输出替换摘要和词汇表占位符注释。不要插入省略术语部分——那仅用于您的透明度消息。
步骤 5: 评审和调整
简要评审生成部分以准确性。子代理可能错过对话中的细微差别——如果需要调整,但当准确时偏好子代理版本(它反映文档实际内容,而非您记忆的内容)。
摘要和词汇表后:提交
提交设计文档:
git add docs/design-plans/YYYY-MM-DD-<主题>.md
git commit -m "$(cat <<'EOF'
docs: 添加[功能名称]设计计划
完成头脑风暴会话。设计包括:
- [关键架构决策 1]
- [关键架构决策 2]
- [N]个实施阶段
EOF
)"
宣布完成:
“设计计划记录在docs/design-plans/YYYY-MM-DD-<主题>.md并提交。”
常见合理化 - 停止
| 借口 | 现实 |
|---|---|
| “我将先写摘要,因为我知道我在构建什么” | 先写正文。总结您写的内容,而非计划的内容。 |
| “我可以自己写摘要和词汇表,不需要子代理” | 子代理有新鲜上下文并作为强制功能。使用它。 |
| “词汇表不需要,术语明显” | 对您头脑风暴后明显。对新鲜评审者不明显。包括它。 |
| “设计简单,不需要阶段” | 阶段使实施可管理。始终包括。 |
| “阶段明显,不需要细节” | 撰写计划需要组件描述。提供它们。 |
| “如果需要可以有10个阶段” | 硬限制是8个。调整范围或拆分。 |
| “我将包括代码以使实施更容易” | 不。实施计划从代码库状态新鲜生成代码。设计仅提供方向。 |
| “分解为任务帮助读者” | 任务分解是实施计划的工作。设计保持在组件级别。 |
| “我将只展示函数如何工作” | 实施代码不属于设计。如果需要,显示契约/接口,而非函数体。 |
| “额外考虑应全面” | 仅在相关时包括。YAGNI适用。 |
| “应记录所有未来可能性” | 仅记录当前设计。无假设。 |
| “现有模式部分可跳过” | 显示调查发生。始终包括。 |
| “可以使用通用文件路径” | 来自调查的确切路径。无模糊。 |
| “测试可以是最后的单独阶段” | 不。功能测试属于创建该功能的阶段。 |
| “我们将在代码工作后添加测试” | 阶段在其测试通过前不完成。测试是交付物,非事后想法。 |
| “基础设施也需要单元测试” | 不。基础设施操作性验证。不要过度工程化。 |
| “阶段3测试将覆盖阶段2代码” | 每个阶段测试其自己的交付物。后期阶段可能扩展测试,但不要推迟。 |
| “阶段标记只是噪音” | 标记启用细粒度解析。实施计划依赖它们。始终包括。 |
| “验收标准只是完成定义重述” | 标准必须是具体和可验证的。“系统安全”变成“API用401拒绝无效令牌”。 |
| “用户批准了DoD,不需要验证标准” | 标准将DoD转化为可测试项。用户必须确认此转化正确。 |
| “我将跳过标准验证以节省时间” | 实施计划依赖已验证标准。跳过创建下游混乱。 |
| “标准从阶段明显” | 对您明显。用户必须在继续前确认他们同意“完成”含义。 |
所有这些意味着:停止。完全遵循结构。
与工作流集成
此技能完成在第3阶段开始的设计文档:
第3阶段(完成定义)完成
-> 用户确认完成定义
-> 文件创建,包含标题、摘要占位符、DoD、AC占位符、词汇表占位符
-> DoD以完整保真度捕获
头脑风暴(第4阶段)完成
-> 已验证设计存在于对话中
-> 用户逐步批准
撰写设计计划(此技能)
-> 附加正文:架构、现有模式、实施阶段、额外考虑
-> 添加来自调查的确切路径
-> 创建离散阶段(<=8)
-> 内联生成验收标准(每个DoD项的成功 + 失败案例)
-> 用户验证验收标准
-> 用已验证标准替换AC占位符
-> 派遣子代理生成摘要和词汇表
-> 用生成内容替换摘要/词汇表占位符
-> 提交到git
撰写实施计划(下一步)
-> 读取此设计文档
-> 使用阶段作为详细任务基础
-> 使用验收标准生成test-requirements.md
-> 期望确切路径和结构
目的: 在设计和实施之间创建契约。撰写计划依赖此结构。可读性头部(摘要、DoD、验收标准、词汇表)确保人工评审者能快速理解文档。验收标准为测试要求提供可追溯性。