mcpField
A
adr-author

adr-author

github.com/delexw开发237 次安装31 周前更新
代码仓库

关于 adr-author

帮助团队按 Michael Nygard 格式编写架构决策记录(ADR)的技能。它引导作者了解现有惯例、确定决策的可执行性等级,并起草和审阅内容,供后续开发者及自动化检查参考。

主要功能

  1. 01检查现有 ADR 惯例
  2. 02厘清决策背景与备选方案
  3. 03选择可执行性等级
  4. 04起草并完善 ADR 章节
  5. 05检查后果与权衡

适用场景

  1. 01为后续开发者记录架构选择
  2. 02明确可由自动化检查验证的决策
  3. 03审阅 ADR 的清晰度与可执行性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/delexw/claude-code-misc --skill adr-author

安装后在 Claude Code 中输入/adr-author确认已加载。

附带文件references/enforceability-patterns.mdreferences/templates.md

详细介绍

ADR 编写指南

帮助用户编写真正能被未来开发者阅读,并能由自动化审查系统执行的架构决策记录。基于 Michael Nygard 在 Documenting Architecture Decisions 中提出的格式。

如何思考 ADR

ADR 记录某个时间点做出的决策。它回答:我们做出了什么决定、为什么,以及由此会产生什么结果?读者是未来的开发者(或 AI 审查者):他们遇到看起来奇怪的代码时,需要了解背后的推理过程。

“决策”部分是 ADR 的核心,也是需要落实执行的部分。其余部分(“背景”和“后果”)提供推理依据,让执行要求显得合理,而非武断。把大部分精力放在“决策”部分,并根据团队的实际需要,写明所需的可执行程度。

工作流

步骤 1:阅读现有 ADR

开始撰写前,先找到并阅读项目现有的 ADR。它们通常位于 docs/adr/、doc/arch/ 或 decisions/。留意以下内容:

  • 编号方案(连续整数、日期前缀等)
  • 章节结构(有些团队会添加“考虑过的替代方案”或“参考资料”)
  • 语气和详细程度
  • 状态约定

遵循现有格式。保持一致比使用任何模板都重要。

步骤 2:理解决策

向用户提问(如果上下文还不够清楚):

  1. 决策是什么? 要做出什么架构选择?
  2. 问题是什么? 哪些因素或矛盾促成了这个决定?
  3. 考虑过哪些替代方案? 即使只是简单提及,也应写入“背景”部分。
  4. 应如何执行? 这决定了可执行程度。

第四个问题是本指南新增的关键问题。大多数 ADR 指南会略过它,但它决定了 ADR 是成为一份持续生效的契约,还是被束之高阁。

步骤 3:选择可执行程度

可执行程度与质量无关——可执行程度为 LOW 的 ADR 也可以写得非常出色。它关乎可行且合适的验证方式。

HIGH — 可通过自动化工具检查是否合规。适用于具体、可衡量的要求:文件路径、数值阈值、版本限制、精确格式。“决策”部分需要至少 2 条具体、可验证的模式。

MEDIUM — 人工审查者可根据明确的指导检查是否合规。适用于需要判断的架构模式、禁止事项和质量指南。“决策”部分需要至少 1 条明确的指南,并且要足够具体,使两位审查者都能就代码是否合规达成一致。

LOW — 仅供参考和了解背景。适用于原则、历史缘由和建议。无需执行机制。这类 ADR 有助于理解现状背后的原因。

询问用户想选择哪个级别。如果他们不确定,可根据决策的性质帮助他们判断:如果可以编写 lint 规则或脚本进行检查,就是 HIGH;如果审查者可以根据明确的标准判断是或否,就是 MEDIUM;如果不同的合理人士可能会有不同的应用方式,就是 LOW。

步骤 4:起草 ADR

使用 Michael Nygard 的四个章节。使用完整的句子和段落来写——ADR 是与未来开发者的对话,而不是需求规格说明书。

# ADR [NUMBER]: [Short noun phrase]

## Status

[Proposed | Accepted | Deprecated | Superseded by ADR-XXX]

## Context

[Forces at play — technological, political, social, project-local.
Present tensions neutrally. Explain why a decision is needed now.]

## Decision

We will [decision in active voice].

[The enforceable substance goes here — see patterns below.]

## Consequences

[What becomes easier, what becomes harder, what new problems arise,
what trade-offs are we accepting. Be honest about downsides.]

格式指南(依据 Nygard 的建议):

  • 总篇幅为一至两页
  • 使用完整的句子和段落,而不只是项目符号列表
  • “决策”部分使用主动语态(“我们将……”而不是“决定……”)
  • “背景”部分使用中性语气,把观点留给“决策”部分
  • 使用连续编号,绝不重复使用
步骤 5:根据目标级别撰写“决策”部分

可执行性模式在这里至关重要。“决策”部分是自动化工具扫描的内容,也是审查者评估 PR 时的依据。

撰写高可执行性决策

HIGH 决策读起来像自然语言,但包含具体、可提取的约束。可以把它看作在易读的文字中嵌入可验证的事实。

支持自动化的六种模式:

  1. 文件路径 — 用反引号标注准确位置

    所有 API 路由都放在 src/api/v2/ 中。组件路径遵循 src/components/{feature}/{ComponentName}.tsx。

  2. 可衡量的约束 — 带单位的数字

    数据库查询将在 30 秒后超时。每个页面的包体积不得超过 250kb。

  3. 配置值 — key:value 或 key=value 键值对

    HTTP 客户端将使用 timeout: 5000。连接池使用 maxConnections = 10。

  4. 版本约束 — 具体的版本要求

    我们将使用 Node.js >= 20.0.0。React 依赖版本将为 ^18.0.0。

  5. 格式规范 — 准确的结构模式

    错误响应遵循以下格式:{error: string, code: number, details?: object}。 提交信息采用以下格式:type(scope): description。

  6. 带有具体对象的声明性陈述 — “将用 X 实现 Y”

    所有新文件都将使用 TypeScript。异步操作将使用 async/await,而不是 Promise 链。

至少包含 2 种此类模式。添加具体示例,说明验证方法(CI 检查、linter 规则、代码审查检查点),并明确注明例外情况。

HIGH 决策示例:

## Decision

We will standardize on Next.js App Router for all new pages.

All new routes will use the `app/` directory structure with files at
`app/{route}/page.tsx`. For example, product detail pages go in
`app/products/[id]/page.tsx`. Components will be Server Components by default —
only add `'use client'` when client-side interactivity is required (forms,
onClick handlers, browser APIs).

Bundle size increases will be limited to 10% per feature. Any use of 'use
client' must be justified in the PR description explaining why server rendering
is insufficient.

The existing `pages/` directory remains for maintenance. New features use `app/`
starting March 2024. Migration happens opportunistically during major updates.

Verification: CI checks that new routes are in `app/` not `pages/`. ESLint rule
flags `'use client'` files without a justification comment.
撰写中等可执行性决策

MEDIUM 决策提供足够明确的指导,让审查者能够判断是否符合要求。这些模式关注的不是精确值,而是明确无歧义的意图。

便于审查者核对的五种决策模式:

  1. 明确的禁止事项 — 我们不会做什么

    新编写的 React 代码不会使用类组件。禁止自定义身份验证;请使用 Auth0。

  2. 实现要求 — 应遵循的模式

    所有端点都将强制执行输入验证。服务将使用依赖注入进行实例化。

  3. 质量/安全指南 — 范围明确的标准

    数据库查询将使用参数化查询;禁止通过直接拼接字符串构造 SQL。所有 HTTP 响应都将设置安全标头。

  4. 架构模式 — 结构性决策

    新服务将采用微服务架构,各自拥有自己的数据并公开 REST API。

  5. 通用要求 — “所有 X 都必须 Y”类陈述

    所有公共函数都将有单元测试。所有 API 变更都将更新 OpenAPI 规范。

加入审查清单,让审查者明确知道要检查什么。

MEDIUM 决策示例:

## Decision

We will standardize error handling across all services.

All async operations will use try-catch blocks. Errors will be wrapped with
context using typed error classes (ValidationError, AuthenticationError,
ExternalServiceError) extending a base ApplicationError. User-facing errors
will not expose internal details — they follow the format:
{message: string, code: string, details?: object}.

All errors will be logged with correlation IDs for request tracing. Sensitive
data will be sanitized before logging.

Review checklist:
- Async operations have try-catch with context
- Appropriate error class is used
- User-facing errors are sanitized
- Errors are logged before handling/re-throwing
撰写低可执行性决策

LOW 决策用于记录理由和原则。它们有助于理解“为什么”,而不规定“如何做”。

## Decision

We chose PostgreSQL over MongoDB for our primary datastore. Our data model is
heavily relational with complex joins across orders, inventory, and customer
records. PostgreSQL's ACID transactions and mature tooling ecosystem align with
our reliability requirements.

We considered MongoDB for its schema flexibility, which would benefit our
rapidly changing product catalog. However, the transactional integrity
requirements for financial data outweigh the flexibility benefits.

Future iterations may introduce a document store for the product catalog if
schema changes become a bottleneck.
第 6 步:审查并完善

根据目标级别检查草稿:

对于 HIGH — 能否编写脚本或 linter 规则来验证每项要求?如果不能,它还不算 HIGH。找出模糊措辞(“适当”“整洁”“良好”),并用具体表述替换。

对于 MEDIUM — 两位独立审查者能否对代码是否符合要求达成一致?如果要求含糊到让合理的人产生分歧,就应让要求更具体(升级为 HIGH),或说明它只是指导(降级为 LOW)。

对于 LOW — 它是否清楚解释了“为什么”,让五年后的开发者也能理解其中的理由?这就是衡量标准。

常见的完善方式:

模糊 → 具体(LOW → HIGH):

Before: "Use good error handling"
After:  "All async functions will use try-catch with structured logging:
         {level: string, message: string, stack?: string}"

抽象 → 具体(LOW → MEDIUM):

Before: "Consider security"
After:  "All user inputs will be validated against SQL injection and XSS
         using the sanitization library"

过于僵化 → 实用(HIGH → MEDIUM):

Before: "All components must be exactly 50 lines or less"
After:  "Components should stay under 100 lines; split when they handle
         multiple concerns"
步骤 7:确保如实说明后果

“后果”部分能够建立信任。如果其中只列出好处,就会像推销词,未来的开发者也不会信任它。请包括:

  • 哪些事情会变得更容易(收益)
  • 哪些事情会变得更困难(成本)
  • 这可能带来哪些新问题(风险)
  • 接受了哪些权衡(有意作出的选择)

常见反模式

模糊的要求:“必须编写整洁的代码” → “必须通过 .eslintrc.js 中的 ESLint 规则,且零警告”

无法执行的绝对要求:“所有代码都必须完美” → “所有公共函数都必须有测试,分支覆盖率 >80%”

未设约束的技术选型:“前端使用 React” → “新组件使用 React >= 18.0.0,并启用 TypeScript 严格模式”

缺少示例:“遵循正确的命名规范” → “函数使用 camelCase(getUserData),组件使用 PascalCase(UserProfile),常量使用 UPPER_SNAKE_CASE(MAX_RETRY_COUNT)”

可执行性混杂:不要在同一个决策部分中,将“文件必须放在 src/ 中”(高)与“采用良好的架构”(低)结合起来。具体程度应保持一致,或拆分为不同级别的独立编号要求。

参考文件

如需本指南未涵盖的更多内容,请阅读以下文件,其中包含全面的模式目录和可直接使用的模板:

  • references/enforceability-patterns.md — 全面的模式类型目录,包含自然表述和规范性表述的示例、模式识别关键词、验证方法,以及各级别之间的升级路径。当你需要识别特定模式,或帮助用户从一个级别升级到另一个级别时,请阅读此文件。

  • references/templates.md — 可复制粘贴的高、中、低可执行性 ADR 模板,每个模板都附有完整示例。用户需要可填写的起始模板时,请阅读此文件。

评论

支持 Markdown