sdd-spec
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesesdd-spec
sdd-spec
Writes delta specifications with requirements and Given/When/Then scenarios.
Triggers: , write specs, specifications, functional requirements, sdd spec
/sdd-spec <change-name>编写包含需求和Given/When/Then场景的增量规格说明。
触发词:、编写规格、规格说明、功能需求、sdd spec
/sdd-spec <变更名称>Purpose
目的
Specs define WHAT the system must do from the perspective of observable behavior. They do not say how to implement it. They are the source of truth for verification.
Key concept — Delta Specs:
Specs are deltas (changes) on top of what already exists, not full replacements.
- If there is no existing spec: I write a complete spec
- If a spec already exists: I write ADDED/MODIFIED/REMOVED sections
规格说明从可观察行为的角度定义系统必须做什么。它们不涉及实现方式,是验证工作的唯一依据。
核心概念 — 增量规格说明(Delta Specs):
规格说明是基于现有内容的增量(变更),而非完全替换。
- 若不存在现有规格说明:我会编写完整的规格说明
- 若已有规格说明:我会编写新增/修改/移除章节
Process
流程
Skill Resolution
技能解析
When the orchestrator launches this sub-agent, it resolves the skill path using:
1. .claude/skills/sdd-spec/SKILL.md (project-local — highest priority)
2. ~/.claude/skills/sdd-spec/SKILL.md (global catalog — fallback)Project-local skills override the global catalog. See for the full algorithm.
docs/SKILL-RESOLUTION.md当编排器启动此子Agent时,它会通过以下路径解析技能:
1. .claude/skills/sdd-spec/SKILL.md (项目本地 — 优先级最高)
2. ~/.claude/skills/sdd-spec/SKILL.md (全局目录 — 备选)项目本地技能会覆盖全局目录。完整算法请参考。
docs/SKILL-RESOLUTION.mdStep 0a — Load project context
步骤0a — 加载项目上下文
Follow Section F (Project Context Load). Non-blocking.
skills/_shared/sdd-phase-common.md遵循中的F章节(项目上下文加载)。此步骤为非阻塞。
skills/_shared/sdd-phase-common.mdStep 0b — Domain context preload
步骤0b — 领域上下文预加载
After loading project context and before identifying affected domains, I perform an optional, non-blocking domain context preload:
- List candidates: List all files in
.md, excludingai-context/features/and any file whose name begins with an underscore. If the directory is absent, skip this step silently._template.md - Apply the filename-stem matching heuristic:
- Split the change slug on hyphens to produce stems; discard any single-character stems.
- For each candidate file, compute its domain slug (filename without extension).
.md - A match occurs when: the domain slug appears in the change name, OR any change-name stem appears in the domain slug (case-insensitive comparison).
- Load matches: If one or more files match, read each file and inject its content as enrichment context before writing the spec. If no file matches, skip silently — do NOT produce an error or warning.
- Multiple matches: If more than one file matches, load all matching files.
- Non-blocking contract: This step MUST NEVER produce or
status: blocked. Any file read error is treated as a miss (skip silently).status: failed - Enrichment note: Feature file content is treated as enrichment context — it surfaces business rules, invariants, and known gotchas that should inform the spec's requirements and THEN clauses. Both feature files and any existing domain specs MUST be read when both are present.
- Orchestrator reporting: When one or more feature files are loaded, the field MUST note that domain context was preloaded (e.g., "domain context loaded from ai-context/features/auth.md"). Each loaded file path MUST appear in the
summarylist (read, not written).artifacts
加载项目上下文后、识别受影响领域之前,我会执行可选的非阻塞领域上下文预加载:
- 列出候选文件:列出目录下所有
ai-context/features/文件,排除.md及名称以下划线开头的文件。若目录不存在,静默跳过此步骤。_template.md - 应用文件名主干匹配启发式规则:
- 将变更slug按连字符拆分得到主干;丢弃单个字符的主干。
- 对每个候选文件,计算其领域slug(不含后缀的文件名)。
.md - 当以下情况发生时视为匹配:领域slug出现在变更名称中,或变更名称的任一主干出现在领域slug中(大小写不敏感比较)。
- 加载匹配文件:若存在一个或多个匹配文件,读取每个文件并将其内容作为增强上下文注入,再编写规格说明。若无匹配文件,静默跳过 — 不产生错误或警告。
- 多匹配情况:若存在多个匹配文件,加载所有匹配文件。
- 非阻塞约定:此步骤绝对不能产生或
status: blocked状态。任何文件读取错误均视为未匹配(静默跳过)。status: failed - 增强说明:功能文件内容作为增强上下文使用 — 它会呈现业务规则、不变量和已知陷阱,这些都应纳入规格说明的需求和THEN子句中。当功能文件和现有领域规格说明同时存在时,必须同时读取两者。
- 编排器报告:当加载一个或多个功能文件时,字段必须注明已预加载领域上下文(例如:“从ai-context/features/auth.md加载领域上下文”)。每个加载的文件路径必须出现在
summary列表中(仅读取,不写入)。artifacts
Step 0c — Spec context preload
步骤0c — 规格上下文预加载
Follow Section G (Spec Context Preload). Non-blocking.
skills/_shared/sdd-phase-common.md遵循中的G章节(规格上下文预加载)。此步骤为非阻塞。
skills/_shared/sdd-phase-common.mdStep 1 — Read prior artifacts
步骤1 — 读取先前工件
I must read:
- The proposal artifact (the WHAT and WHY):
- →
mem_search(query: "sdd/{change-name}/proposal")for full content.mem_get_observation(id) - If not found and Engram not reachable: proposal content passed inline from orchestrator.
- if it exists (to understand the current system)
ai-context/architecture.md
我必须读取:
- 提案工件(包含WHAT和WHY):
- → 调用
mem_search(query: "sdd/{change-name}/proposal")获取完整内容。mem_get_observation(id) - 若未找到且Engram不可达:提案内容由编排器内联传递。
- 若存在(用于理解当前系统)
ai-context/architecture.md
Step 1 extended — Validate against Supersedes section
步骤1扩展 — 针对Supersedes章节的验证
After reading the proposal, I perform a Supersedes cross-check before writing any spec:
-
Check for Supersedes section: look forin the proposal.
## Supersedes- If absent (older archived change): log and proceed without validation.
WARNING: proposal has no Supersedes section — backwards compat mode; skipping validation - If present and states "None — purely additive": skip validation; proceed to Step 2.
- If present with REMOVED or REPLACED items: proceed to step 2 below.
- If absent (older archived change): log
-
For each REMOVED item in Supersedes: scan the delta spec I am about to write for any requirement that says "preserve X", "X MUST remain", or "backward compatibility with X". If found:
- Emit warning: "Spec includes a preservation requirement for '[X]' but proposal says '[X]' is REMOVED. Confirm intent."
MUST_RESOLVE - Pause for user confirmation before continuing.
- Emit
-
For each REPLACED item in Supersedes: verify the spec describes the new replacement, not the old behavior. If spec only describes old behavior without acknowledging replacement, add a note:.
[PENDING: spec does not describe replacement behavior for [X] — clarify with design] -
For CONTRADICTED items: verify the spec aligns with the resolution documented inof the proposal. If mismatch, emit
## Contradiction Resolutionwarning.MUST_RESOLVE
读取提案后,在编写任何规格说明之前,我会执行Supersedes交叉检查:
-
检查Supersedes章节:在提案中查找章节。
## Supersedes- 若不存在(旧的归档变更):记录并继续执行,不进行验证。
WARNING: 提案无Supersedes章节 — 向后兼容模式;跳过验证 - 若存在且声明为“None — purely additive”:跳过验证;继续执行步骤2。
- 若存在且包含REMOVED或REPLACED项:继续执行下方步骤2。
- 若不存在(旧的归档变更):记录
-
针对Supersedes中的每个REMOVED项:扫描我即将编写的增量规格说明,查找任何包含“保留X”、“X必须保留”或“与X向后兼容”的需求。若找到:
- 发出警告:“规格说明包含对'[X]'的保留需求,但提案声明'[X]'已被移除。请确认意图。”
MUST_RESOLVE - 暂停并等待用户确认后再继续。
- 发出
-
针对Supersedes中的每个REPLACED项:验证规格说明描述的是新的替代功能,而非旧行为。若规格说明仅描述旧行为且未提及替代,添加注释:。
[待处理:规格说明未描述[X]的替代行为 — 请与设计团队澄清] -
针对矛盾项:验证规格说明与提案中章节记录的解决方案一致。若不匹配,发出
## Contradiction Resolution警告。MUST_RESOLVE
Step 2 — Identify affected domains
步骤2 — 识别受影响领域
From the proposal I extract the domains that need specs:
- One domain = one coherent functional area (auth, payments, users, notifications, etc.)
- Each domain has its own spec file
从提案中提取需要编写规格说明的领域:
- 一个领域 = 一个连贯的功能区域(认证、支付、用户、通知等)
- 每个领域有其独立的规格文件
Step 3 — Write delta specs
步骤3 — 编写增量规格说明
For each affected domain, I persist the delta spec to engram:
Call with , , , content = all domain specs concatenated (separated by ). Do NOT write any file.
mem_savetopic_key: sdd/{change-name}/spectype: architectureproject: {project}---If Engram MCP is not reachable: skip persistence. Return spec content inline only.
Content format:
对每个受影响的领域,我会将增量规格说明持久化到Engram:
调用,参数为、、,内容 = 所有领域规格说明的拼接结果(用分隔)。不要写入任何文件。
mem_savetopic_key: sdd/{change-name}/spectype: architectureproject: {project}---若Engram MCP不可达:跳过持久化步骤。仅内联返回规格说明内容。
内容格式:
If NO existing spec — Full spec:
若无现有规格说明 — 完整规格说明:
markdown
undefinedmarkdown
undefinedSpec: [Domain]
规格说明:[领域]
Change: [change-name]
Date: [YYYY-MM-DD]
变更:[change-name]
日期:[YYYY-MM-DD]
Requirements
需求
Requirement: [Descriptive name]
需求:[描述性名称]
[Description using RFC 2119 keywords]
[使用RFC 2119关键字的描述]
Scenario: [Case name]
场景:[案例名称]
- GIVEN [precondition — system state]
- WHEN [action — what happens]
- THEN [observable result — what must happen]
- AND [additional result if applicable]
- GIVEN [前置条件 — 系统状态]
- WHEN [动作 — 发生的事件]
- THEN [可观察结果 — 必须发生的情况]
- AND [若适用,附加结果]
Scenario: [Edge case]
场景:[边缘情况]
- GIVEN [...]
- WHEN [...]
- THEN [...]
undefined- GIVEN [...]
- WHEN [...]
- THEN [...]
undefinedIf spec ALREADY EXISTS — Delta:
若已有规格说明 — 增量:
markdown
undefinedmarkdown
undefinedDelta Spec: [Domain]
增量规格说明:[领域]
Change: [change-name]
Date: [YYYY-MM-DD]
变更:[change-name]
日期:[YYYY-MM-DD]
ADDED — New requirements
ADDED — 新增需求
Requirement: [Name]
需求:[名称]
[Description]
[描述]
Scenario: [Name]
场景:[名称]
- GIVEN [...]
- WHEN [...]
- THEN [...]
- GIVEN [...]
- WHEN [...]
- THEN [...]
MODIFIED — Modified requirements
MODIFIED — 修改的需求
Requirement: [Name of existing requirement]
需求:[现有需求名称]
[New description]
(Before: [previous description])
[新描述]
(之前:[原描述])
Scenario: [Name] (modified)
场景:[名称] (已修改)
- GIVEN [...]
- WHEN [...]
- THEN [...]
- GIVEN [...]
- WHEN [...]
- THEN [...]
REMOVED — Removed requirements
REMOVED — 移除的需求
Requirement: [Name]
需求:[名称]
(Reason: [why it is being removed])
undefined(原因:[移除理由])
undefinedRFC 2119 Keywords (required)
RFC 2119关键字(必填)
| Keyword | Meaning |
|---|---|
| MUST | Absolute requirement |
| MUST NOT | Absolute prohibition |
| SHOULD | Recommended (exceptions allowed with justification) |
| MAY | Optional |
| 关键字 | 含义 |
|---|---|
| MUST | 绝对要求 |
| MUST NOT | 绝对禁止 |
| SHOULD | 推荐(有正当理由时可例外) |
| MAY | 可选 |
Types of scenarios to cover
需覆盖的场景类型
For each requirement I include:
- Happy path: The normal, successful flow
- Edge cases: Extreme values, empty lists, maximums
- Error cases: What happens when something fails
- Security cases: If applicable (authentication, authorization, permissions)
对每个需求,我会包含:
- 正常路径:常规、成功的流程
- 边缘情况:极值、空列表、最大值等
- 错误情况:当出现故障时的表现
- 安全场景:若适用(认证、授权、权限等)
Examples of well-written scenarios
编写良好的场景示例
Well written
优秀示例
undefinedundefinedScenario: Successful login with valid credentials
场景:使用有效凭据成功登录
- GIVEN that the user exists with email "user@example.com" and the correct password
- WHEN they send POST /auth/login with those credentials
- THEN they receive status 200
- AND they receive a valid JWT in the "token" field
- AND the token expires in 24 hours
- GIVEN 用户存在,邮箱为"user@example.com"且密码正确
- WHEN 他们发送POST /auth/login请求并携带这些凭据
- THEN 他们收到状态码200
- AND 他们在"token"字段中收到有效的JWT
- AND 令牌24小时后过期
Scenario: Failed login with incorrect password
场景:使用错误密码登录失败
- GIVEN that the user exists with email "user@example.com"
- WHEN they send POST /auth/login with an incorrect password
- THEN they receive status 401
- AND the error message does NOT reveal whether the email exists
undefined- GIVEN 用户存在,邮箱为"user@example.com"
- WHEN 他们发送POST /auth/login请求并携带错误密码
- THEN 他们收到状态码401
- AND 错误信息不会泄露该邮箱是否存在
undefinedPoorly written (too vague)
编写不佳的示例(过于模糊)
undefinedundefinedScenario: The user can log in
场景:用户可以登录
- GIVEN there is a user
- WHEN they log in
- THEN it works
---- GIVEN 存在一个用户
- WHEN 他们登录
- THEN 登录成功
---Output to Orchestrator
向编排器输出
json
{
"status": "ok|warning|blocked",
"summary": "Specs for [change-name]: [N] domains, [M] requirements, [K] scenarios.",
"artifacts": ["engram:sdd/{change-name}/spec"],
"next_recommended": ["sdd-tasks (after sdd-design)"],
"risks": []
}json
{
"status": "ok|warning|blocked",
"summary": "变更[change-name]的规格说明:[N]个领域,[M]条需求,[K]个场景。",
"artifacts": ["engram:sdd/{change-name}/spec"],
"next_recommended": ["sdd-tasks (after sdd-design)"],
"risks": []
}Rules
规则
- Specs describe OBSERVABLE BEHAVIOR, not implementation
- Each requirement MUST have at least 1 scenario (happy path minimum)
- Scenarios MUST be testable and verifiable
- I do NOT include implementation details (that is )
sdd-design - I do NOT invent behavior — I base everything on the proposal and existing code
- If something is ambiguous in the proposal, I mark it as and list it in risks
[Pending clarification] - I do NOT add "preserve X" or "backward compatibility with X" requirements that are NOT explicitly stated in the proposal — if the proposal is silent, treat as pending clarification, NOT as implicit preservation
- If the proposal has no Supersedes section (archived change compatibility), I skip validation and proceed without error — backwards compat mode is non-blocking
- 规格说明描述可观察行为,而非实现细节
- 每条需求必须至少包含1个场景(至少正常路径)
- 场景必须可测试、可验证
- 我不会包含实现细节(那是的职责)
sdd-design - 我不会凭空创造行为 — 所有内容均基于提案和现有代码
- 若提案中存在模糊内容,我会标记为并列入风险列表
[待澄清] - 我不会添加提案中未明确说明的“保留X”或“与X向后兼容”需求 — 若提案未提及,视为待澄清,而非隐含需要保留
- 若提案无Supersedes章节(归档变更兼容),我会跳过验证并继续执行 — 向后兼容模式为非阻塞