sdd-design

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

sdd-design

sdd-design

Produces the technical design with architecture decisions, data flow, and a file change plan.
Triggers:
/sdd-design <change-name>
, technical design, change architecture, sdd design

生成包含架构决策、数据流和文件变更计划的技术设计。
触发方式:
/sdd-design <变更名称>
、technical design、change architecture、sdd design

Purpose

目的

The design defines HOW to implement what the specs say the system MUST do. It is the bridge between requirements and code. It documents technical decisions and their justification.

本设计定义了如何实现需求规格中规定的系统必须完成的内容,是需求与代码之间的桥梁。它记录了技术决策及其依据。

Process

流程

Skill Resolution

技能解析

When the orchestrator launches this sub-agent, it resolves the skill path using:
1. .claude/skills/sdd-design/SKILL.md     (project-local — highest priority)
2. ~/.claude/skills/sdd-design/SKILL.md   (global catalog — fallback)
Project-local skills override the global catalog. See
docs/SKILL-RESOLUTION.md
for the full algorithm.

当编排器(Orchestrator)启动该子Agent时,它会通过以下路径解析技能:
1. .claude/skills/sdd-design/SKILL.md     (项目本地 — 优先级最高)
2. ~/.claude/skills/sdd-design/SKILL.md   (全局目录 — 备用)
项目本地技能会覆盖全局目录技能。完整算法请参考
docs/SKILL-RESOLUTION.md

Step 0 — Load project context + Spec context preload

步骤0 — 加载项目上下文 + 预加载规格上下文

Follow
skills/_shared/sdd-phase-common.md
Section F (Project Context Load) and Section G (Spec Context Preload). Both are non-blocking.

遵循
skills/_shared/sdd-phase-common.md
中的F部分(项目上下文加载)G部分(规格上下文预加载),两者均为非阻塞操作。

Step 1 — Read prior artifacts

步骤1 — 读取先前的工件

I must read:
  • The proposal artifact:
    • mem_search(query: "sdd/{change-name}/proposal")
      mem_get_observation(id)
      .
    • If not found and Engram not reachable: proposal content passed inline from orchestrator.
  • The spec artifact:
    • mem_search(query: "sdd/{change-name}/spec")
      mem_get_observation(id)
      .
    • If not found and Engram not reachable: spec content passed inline from orchestrator.
  • ai-context/architecture.md
    if it exists
  • ai-context/conventions.md
    if it exists
Then I read real code:
  • Relevant entry points
  • Files that will be affected according to the proposal
  • Existing patterns to follow (not reinvent)
  • Existing tests (they reveal current contracts)
我必须读取:
  • 提案工件:
    • mem_search(query: "sdd/{变更名称}/proposal")
      mem_get_observation(id)
    • 如果未找到且Engram不可访问:提案内容由编排器直接传入。
  • 规格工件:
    • mem_search(query: "sdd/{变更名称}/spec")
      mem_get_observation(id)
    • 如果未找到且Engram不可访问:规格内容由编排器直接传入。
  • 若存在
    ai-context/architecture.md
  • 若存在
    ai-context/conventions.md
然后我会读取实际代码:
  • 相关入口点
  • 提案中提到的会受影响的文件
  • 需要遵循的现有模式(避免重复造轮子)
  • 现有测试(它们能体现当前的契约)

Step 2 — Design the technical solution

步骤2 — 设计技术解决方案

I evaluate the solution considering:
  • Patterns already used in the project (prefer consistency)
  • Minimal impact on existing code
  • Testability
  • Reversibility (rollback plan from the proposal)
我会从以下方面评估解决方案:
  • 项目中已使用的模式(优先保持一致性)
  • 对现有代码的影响最小化
  • 可测试性
  • 可回滚性(提案中的回滚计划)

Skills Registry cross-reference

技能注册表交叉引用

When recommending a skill, library, or technology pattern in the design, I MUST check the project Skills Registry extracted in Step 0 and follow these rules:
  • Registered skill: reference it by its exact registered name (e.g.,
    typescript
    ,
    react-19
    ).
  • Global catalog skill, not registered in project: mark it as optional with a note, e.g.
    [optional — not registered in project; add via /skill-add <name>]
    .
  • Skill not in the global catalog: state it as a new dependency and flag it for review.
This check applies to the Technical Decisions table, the Testing Strategy table, and any inline recommendations in the design narrative. It ensures design output stays aligned with the project's declared toolset.
当在设计中推荐技能、库或技术模式时,我必须检查步骤0中提取的项目技能注册表,并遵循以下规则:
  • 已注册技能:使用其准确的注册名称引用(例如:
    typescript
    react-19
    )。
  • 全局目录技能,但未在项目中注册:标记为可选并添加说明,例如
    [可选 — 未在项目中注册;通过/skill-add <名称>添加]
  • 未在全局目录中的技能:说明这是新依赖并标记为需要审核。
此检查适用于技术决策表、测试策略表以及设计叙述中的任何内联建议。它确保设计输出与项目声明的工具集保持一致。

Step 3 — Create design.md

步骤3 — 创建design.md

I persist the design artifact to engram:
Call
mem_save
with
topic_key: sdd/{change-name}/design
,
type: architecture
,
project: {project}
, content = full design markdown. Do NOT write any file.
If Engram MCP is not reachable: skip persistence. Return design content inline only.
Content format:
markdown
undefined
我会将设计工件持久化到Engram:
调用
mem_save
,参数为
topic_key: sdd/{变更名称}/design
type: architecture
project: {项目}
,content为完整的设计markdown内容。不要写入任何文件
如果Engram MCP不可访问:跳过持久化,仅返回设计内容。
内容格式:
markdown
undefined

Technical Design: [change-name]

Technical Design: [变更名称]

Date: [YYYY-MM-DD] Proposal: engram:sdd/[name]/proposal
Date: [YYYY-MM-DD] Proposal: engram:sdd/[名称]/proposal

General Approach

总体方案

[High-level description of the technical solution in 3-5 lines]
[用3-5行描述技术解决方案的高层内容]

Technical Decisions

技术决策

DecisionChoiceDiscarded AlternativesJustification
[decision][what is chosen][alternative A, alternative B][why this choice]
决策项选择方案弃用的替代方案决策依据
[决策内容][所选方案][替代方案A, 替代方案B][选择原因]

Data Flow

数据流

[ASCII diagram or description of the flow]
Example:

Request → Middleware → Controller → Service → Repository → DB
Validator (Zod)
Response DTO
[ASCII图或流程描述]
示例:

Request → Middleware → Controller → Service → Repository → DB
Validator (Zod)
Response DTO

File Change Matrix

文件变更矩阵

FileActionWhat is added/modified
src/modules/auth/auth.service.ts
ModifyAdd
refreshToken()
method
src/modules/auth/auth.controller.ts
ModifyNew endpoint POST /auth/refresh
src/modules/auth/dto/refresh.dto.ts
CreateDTO for refresh request
src/modules/auth/auth.module.ts
ModifyRegister new provider
tests/auth/refresh-token.spec.ts
CreateTests for the new endpoint
文件操作添加/修改内容
src/modules/auth/auth.service.ts
修改添加
refreshToken()
方法
src/modules/auth/auth.controller.ts
修改新增POST /auth/refresh端点
src/modules/auth/dto/refresh.dto.ts
创建刷新请求的DTO
src/modules/auth/auth.module.ts
修改注册新的提供者
tests/auth/refresh-token.spec.ts
创建新端点的测试用例

Interfaces and Contracts

接口与契约

[Type definitions, interfaces, DTOs, schemas to be created]
typescript
// Example
interface RefreshTokenRequest {
  refreshToken: string;
}

interface RefreshTokenResponse {
  accessToken: string;
  expiresIn: number;
}
[要创建的类型定义、接口、DTO、模式]
typescript
// 示例
interface RefreshTokenRequest {
  refreshToken: string;
}

interface RefreshTokenResponse {
  accessToken: string;
  expiresIn: number;
}

Testing Strategy

测试策略

LayerWhat to testTool
Unit[service/function][jest/vitest/pytest]
Integration[endpoint/module][supertest/httpx]
E2E[full flow if applicable][playwright/cypress]
层级测试内容工具
单元测试[服务/函数][jest/vitest/pytest]
集成测试[端点/模块][supertest/httpx]
端到端测试[适用的完整流程][playwright/cypress]

Migration Plan

迁移计划

[If there are changes to DB, schema, or existing data:]
  • Step 1: [migration script]
  • Step 2: [gradual rollout if applicable]
  • Step 3: [post-cleanup]
[If no migration: "No data migration required."]
[如果涉及数据库、模式或现有数据变更:]
  • 步骤1:[迁移脚本]
  • 步骤2:[适用的逐步部署]
  • 步骤3:[后期清理]
[如果无需迁移:"无需数据迁移。"]

Open Questions

待解决问题

[Aspects that need clarification before implementing]
  • [question]: [impact if not resolved]
[If none: "None."]
undefined
[实施前需要澄清的方面]
[如果没有:"无。"]
undefined

Step 4 — ADR Detection and Generation

步骤4 — ADR检测与生成

This step is non-blocking: any failure produces a warning in the output, never
status: blocked
or
status: failed
.
  1. Scan for significant decisions: read the Technical Decisions table in the newly created
    design.md
    . For each row, check whether the text (across all columns) contains any of the following keywords (case-insensitive):
    pattern
    ,
    convention
    ,
    cross-cutting
    ,
    replaces
    ,
    introduces
    ,
    architecture
    ,
    global
    ,
    system-wide
    ,
    breaking
  2. No match → skip silently: if no row matches any keyword, do nothing and produce no output for this step.
  3. Match found → generate ADR: a. Prerequisite check: if
    docs/templates/adr-template.md
    does not exist OR
    docs/adr/README.md
    does not exist, log the warning
    "ADR infrastructure not found (docs/templates/adr-template.md or docs/adr/README.md missing) — skipping ADR generation"
    and stop this step. b. Determine next ADR number: count existing files matching
    docs/adr/[0-9][0-9][0-9]-*.md
    . The next number is
    count + 1
    , zero-padded to 3 digits (e.g.,
    001
    ,
    012
    ,
    100
    ). c. Derive slug:
    <NNN>-<change-name>[-<first-matched-keyword>]
    , all lowercase, spaces replaced with hyphens, non-alphanumeric characters (except hyphens) removed, truncated to 50 characters. d. Copy template: copy
    docs/templates/adr-template.md
    to
    docs/adr/<slug>.md
    . e. Pre-fill content in the new ADR file:
    • Title (H1): derived from the slug (replace hyphens with spaces, title-case)
    • Status:
      Proposed
    • Context section: content from the Justification column of the first matched row
    • Decision section: content from the Choice column of the first matched row f. Update index: append a new row to the ADR index table in
      docs/adr/README.md
      :
      | [NNN] | [Title] | Proposed | [YYYY-MM-DD] | [brief one-line context] |
      g. Artifacts: add
      docs/adr/<slug>.md
      to the artifacts list.

此步骤为非阻塞:任何失败仅会在输出中产生警告,不会返回
status: blocked
status: failed
  1. 扫描重大决策:读取新创建的
    design.md
    中的技术决策表。对于每一行,检查所有列的文本是否包含以下任意关键字(不区分大小写):
    pattern
    ,
    convention
    ,
    cross-cutting
    ,
    replaces
    ,
    introduces
    ,
    architecture
    ,
    global
    ,
    system-wide
    ,
    breaking
  2. 无匹配项 → 静默跳过:如果没有行匹配任何关键字,则不执行任何操作,此步骤无输出。
  3. 找到匹配项 → 生成ADR: a. 前提检查:如果
    docs/templates/adr-template.md
    不存在
    docs/adr/README.md
    不存在,记录警告
    "未找到ADR基础设施(docs/templates/adr-template.md或docs/adr/README.md缺失)—— 跳过ADR生成"
    并停止此步骤。 b. 确定下一个ADR编号:统计匹配
    docs/adr/[0-9][0-9][0-9]-*.md
    的现有文件数量。下一个编号为
    count + 1
    ,补零至3位(例如:
    001
    ,
    012
    ,
    100
    )。 c. 生成slug
    <NNN>-<变更名称>[-<第一个匹配的关键字>]
    ,全部小写,空格替换为连字符,移除非字母数字字符(连字符除外),截断至50个字符。 d. 复制模板:将
    docs/templates/adr-template.md
    复制到
    docs/adr/<slug>.md
    。 e. 预填充内容到新的ADR文件中:
    • 标题(H1):由slug转换而来(连字符替换为空格,首字母大写)
    • 状态:
      Proposed
    • 上下文部分:第一个匹配行的决策依据列内容
    • 决策部分:第一个匹配行的选择方案列内容 f. 更新索引:在
      docs/adr/README.md
      的ADR索引表中添加新行:
      | [NNN] | [标题] | Proposed | [YYYY-MM-DD] | [简短的单行上下文] |
      g. 工件:将
      docs/adr/<slug>.md
      添加到工件列表中。

Examples of well-documented decisions

记录良好的决策示例

Well documented

记录良好

markdown
| Input validation | Zod at controller layer | Class-validator, manual |
The project already uses Zod for DB schemas (Drizzle).
Maintaining consistency avoids two validation systems. |
markdown
| 输入验证 | 在控制器层使用Zod | Class-validator、手动验证 |
项目已在数据库模式(Drizzle)中使用Zod。保持一致性可避免两套验证系统。 |

Poorly documented

记录不佳

markdown
| Validation | Zod | others | It's better |

markdown
| 验证 | Zod | 其他 | 更好用 |

Useful ASCII diagrams

实用的ASCII图

undefined
undefined

Authentication flow

认证流程

Client → POST /auth/login ↓ AuthController ↓ AuthService.validateCredentials() ↓ UserRepository.findByEmail() ↓ bcrypt.compare(password, hash) ↓ (success) JwtService.sign(payload) ↓ Response { token, refreshToken }
Client → POST /auth/login ↓ AuthController ↓ AuthService.validateCredentials() ↓ UserRepository.findByEmail() ↓ bcrypt.compare(password, hash) ↓ (成功) JwtService.sign(payload) ↓ Response { token, refreshToken }

Module structure

模块结构

auth/ ├── auth.module.ts ├── auth.controller.ts ├── auth.service.ts ├── strategies/ │ ├── jwt.strategy.ts │ └── local.strategy.ts └── dto/ ├── login.dto.ts └── refresh.dto.ts
undefined
auth/ ├── auth.module.ts ├── auth.controller.ts ├── auth.service.ts ├── strategies/ │ ├── jwt.strategy.ts │ └── local.strategy.ts └── dto/ ├── login.dto.ts └── refresh.dto.ts
undefined

Step 5 — Summary to orchestrator

步骤5 — 向编排器返回摘要

I return a clear executive summary to the orchestrator with all artifacts produced (design.md and any ADR file created in Step 4).

我会向编排器返回清晰的执行摘要,包含所有生成的工件(design.md以及步骤4中创建的任何ADR文件)。

Output to Orchestrator

向编排器输出

json
{
  "status": "ok|warning|blocked",
  "summary": "Design for [change-name]: [N] affected files, approach [brief description], risk [level].",
  "artifacts": ["engram:sdd/{change-name}/design"],
  "next_recommended": ["sdd-tasks (requires spec + design completed)"],
  "risks": ["[technical risk if found]"]
}

json
{
  "status": "ok|warning|blocked",
  "summary": "Design for [变更名称]: [N]个受影响文件,方案[简要描述],风险[等级]。",
  "artifacts": ["engram:sdd/{变更名称}/design"],
  "next_recommended": ["sdd-tasks (requires spec + design completed)"],
  "risks": ["[发现的技术风险]"]
}

Rules

规则

  • ALWAYS read real code before designing — never assume the structure
  • Every decision MUST have justification (the "why", not just the "what")
  • Follow existing project patterns unless the change explicitly corrects them
  • The file matrix must be concrete (real paths, not "some auth file")
  • ASCII diagrams are preferable to long descriptions
  • If I detect that the proposal is incompatible with the current architecture, I report it as a blocker
  • I do NOT write implementation code — that is
    sdd-apply
  • 必须先读取实际代码再进行设计 — 绝不假设代码结构
  • 每个决策都必须有依据(即"为什么",而不仅仅是"做什么")
  • 遵循项目现有模式,除非变更明确需要纠正这些模式
  • 文件矩阵必须具体(真实路径,而非"某个认证文件")
  • 优先使用ASCII图而非长篇描述
  • 如果发现提案与当前架构不兼容,需将其报告为阻塞项
  • 不会编写实现代码 — 那是
    sdd-apply
    的职责