关于 escrever-trd
用于创建、维护项目全局技术需求文档 TRD 的技能,适合采用 SDD 工作流的项目团队。它会检查项目文件、补充外部资料,并仅就未解决的信息进行访谈;也可记录 ADR。
主要功能
- 01自动识别创建或编辑模式
- 02分析项目结构与技术栈
- 03搜索外部依赖的公开约束
- 04针对信息缺口进行访谈
- 05生成或更新 TRD 与 ADR
适用场景
- 01为新项目生成 docs/trd.md
- 02将现有 TRD 与项目现状对照
- 03补录项目的全局技术决策
- 04从源文档整理无代码项目的 TRD
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fabricioveronez/ harness-publico --skill escrever-trd安装后在 Claude Code 中输入/escrever-trd确认已加载。
附带文件references/template-adr.mdreferences/template-trd.md
详细介绍
编写 TRD
在 docs/trd.md 中创建并维护 TRD(Technical Requirements Document,技术需求文档)。TRD 是项目的全局技术文档:唯一一份,由 sdd 工作流中的技能维护和查阅。涵盖全局且稳定的内容——技术栈、架构、非功能性需求、外部依赖、规范和决策。特定功能的需求放在 PRD 中;个别决策的详细信息放在 ADR 中。
此技能会自动分析项目,通过外部搜索补充信息,并且只会就尚未明确的问题采访用户——目标是尽量减少沟通成本,最大限度地推断出可确定的信息。
输入
用户可以通过以下方式调用此技能:
- 不带参数:此技能会根据是否存在
docs/trd.md自动检测模式 - “更新”“编辑”“TRD 有变”“技术栈有变”:确认进入编辑模式
- “创建”“新建 TRD”:确认进入创建模式
模式
系统会根据 docs/trd.md 是否存在,自动检测创建模式还是编辑模式——用户无需指定。决策模式由明确意图触发(记录决策/创建 ADR),并优先于自动检测。
- 创建模式——
docs/trd.md不存在:分析项目,通过外部搜索补充信息,仅针对未明确之处进行简短采访,并根据references/template-trd.md生成包含 6 个章节的 TRD。 - 编辑模式——
docs/trd.md存在:重新分析项目,并与当前 TRD 对比;仅针对不一致之处进行采访,并在保留正确内容的同时更新文档。 - 决策模式——将技术决策记录为
docs/adrs/NNN-slug.md中的 ADR(状态为aceito后不可修改),并更新 TRD 的“全局决策”章节。由明确请求触发(“记录……决策”“创建 ADR”);无论 TRD 是否已存在,都可以使用。
执行流程
创建模式
当 docs/trd.md 不存在时运行。目标是在尽可能减少沟通成本的前提下生成完整的 TRD:大部分内容应来自自动分析和补充信息;采访仅针对实际存在的信息缺口。
步骤 0——尚无代码的项目(基于源文档)
当项目尚无代码时——通常是在进行系统构思(brainstorm-for-systems)之后——没有文件可供分析。此时以源文档(构思内容的汇总,或用户指定的其他文档)为信息来源:从中提取技术栈、架构、非功能性需求和外部依赖,跳过步骤 1,对其中提到的依赖执行外部信息补充(步骤 2),并且只针对信息缺口进行采访。文档标记为已验证的项目,应注明信息来源和查询日期。
第 1 步 — 自动分析项目
提出任何问题之前,请检查以下文件和模式。这里推断得越多,访谈就越短;访谈简短,说明这项技能运行良好。
技术栈:
package.json/ lockfiles → 语言、运行时、主要依赖、框架、测试工具tsconfig.json→ TypeScript 配置、模块系统、targetpyproject.toml/requirements.txt/setup.py→ Python 技术栈go.mod→ Go 技术栈Cargo.toml→ Rust 技术栈Makefile、justfile→ 构建和测试命令
模式:
.eslintrc*、.prettierrc*、ruff.toml、clippy.toml→ lint 和格式化jest.config.*、vitest.config.*、pytest.ini→ 测试框架和配置package.json中的测试脚本 → 测试命令
架构:
- 文件夹结构(2 层)→ 架构模式和组织方式
- 1-2 个有代表性的源文件 → 命名规范和错误处理方式
外部依赖(部分推断):
package.json/ lockfiles → 已知的第三方 SDK(例如:stripe、@sendgrid/mail、firebase-admin),它们表明存在外部集成;不要列出所有库,只列出那些会带来契约、速率限制或相关架构行为的库.env.example/.env.sample→ 引用外部 API URL 或密钥的变量 (例如:STRIPE_SECRET_KEY、REDIS_URL、AUTH0_DOMAIN),可以揭示不明显的依赖docker-compose.yml/docker-compose.yaml→ 声明的服务(例如:Redis、Postgres、 RabbitMQ),即项目在开发过程中依赖的服务terraform/、infra/、k8s/→ 揭示云依赖的基础设施资源
非功能性需求(有限推断):
- 基础设施配置文件可能揭示约束(例如:
docker-compose中的内存限制、 代理/网关配置中的超时) - 通常,NFR 很少写在文件中,因此是访谈的优先候选项
分析完成后,在内部整理有把握的推断和仍不确定的内容。不确定之处将作为第 2 步和第 3 步的输入。
步骤 2 — 通过外部搜索补充信息
对于步骤 1 中识别出的每项外部依赖,在询问用户之前主动搜索相关公开约束——文档已经给出答案的问题,再去询问只会徒增沟通成本。
如何搜索:
使用任何可访问文档或进行相关查询的 MCP 或工具——WebSearch、语言/框架文档 MCP、特定服务的 MCP(例如用于库的 context7),或会话中可用的其他工具。判断标准是:该工具能否返回关于服务的可靠技术信息?
- 优先搜索文档公开且稳定的服务信息:速率限制、SLA、默认行为、超时、连接限制和配额
- 对于项目的内部系统,不要搜索——这些信息只能通过采访用户获取
- 如果同一服务有多个可用工具,优先选择更专业的工具(例如:该服务的 MCP > 通用 WebSearch)
如何记录:
- 在内部记录搜索结果及其来源(例如
[WebSearch]、[context7]、[MCP stripe]) - 将结果视为预填建议,而非已确认事实——用户会在写入之前通过预览进行确认
- 如果搜索未能返回可靠结果,或文档含糊不清,则将其归类为信息缺口,并正常纳入访谈
待搜索的约束示例:
| 检测到的服务 | 搜索内容 |
|---|---|
Stripe / @stripe/stripe-js | 每个端点的速率限制、幂等行为 |
Redis / ioredis | 默认最大连接数、TTL 上限、内存耗尽时的行为 |
SendGrid / @sendgrid/mail | 发送速率限制、退信限制 |
Auth0 / auth0 | 身份验证速率限制、令牌默认过期时间 |
AWS S3 / @aws-sdk/client-s3 | 对象大小限制、请求速率限制 |
Firebase / firebase-admin | Firestore 读写限制、配额 |
步骤 3 — 针对信息缺口进行简短访谈
只询问无法通过推断或外部搜索补充的信息。问题数量限制为**≤5 个**(PRD 目标;可接受的最大值:8 个)。为什么要设此限制?如果需要更多问题,问题出在分析和信息补充上,而不是用户身上——访谈应是补充手段,而非主要途径。
步骤 2 中已补充信息的依赖项不会产生问题——只会作为建议显示在预览中供用户确认。只有在搜索未能返回可靠结果时,才询问外部依赖。
每条消息最多合并 2 个相关问题,以减少来回沟通。优先顺序:
- 技术栈信息缺口(语言或运行时不明确时)
- 架构模式(目录结构未能揭示时)
- 测试命令(未在脚本或配置中找到时)
- 约定(没有 lint 或格式化配置时)
- 主要非功能需求(基础设施文件中没有相关线索时): 将预期性能、SLA 和安全限制合并为一个问题——NFR 很少能通过推断得出,却会对计划产生重大影响
- 不明显的外部依赖(
.env.example或 lockfile 未能揭示,且外部搜索也未覆盖时):询问项目会调用哪些第三方 API 或内部服务,以及是否有速率限制或合同需要遵守 - ADR 的位置(不存在
docs/adrs/,且用户可能使用其他路径时)
优先级 5 和 6 都存在信息缺口时,可以合并到一条消息中,同时保持消息往返次数 ≤5。
第 4 步 — 扫描 ADR(US03)
扫描 docs/adrs/,查找现有 ADR。对于找到的每个文件,提取:
- 标题:来自 H1 或文件名
- 日期:来自 frontmatter 或文件名前缀
- 状态:frontmatter 的
status字段,或正文中的关键词(已接受/已弃用) - 链接:相对于
docs/trd.md的路径
状态为 已弃用 的 ADR 应使用视觉标记 ~~标题~~ 列出——绝不移除。
不要内联 ADR 内容:它们可能很长,且会独立于 TRD 变化。
如果 docs/adrs/ 不存在,请在该部分使用 *(尚无记录的决策)*。如果用户提供了其他路径,则扫描该路径。
第 5 步 — 预览和写入
使用 references/template-trd.md 作为规范结构,生成 6 个部分。写入前,向用户展示每个部分的预览并征求确认。第 2 步中得出的建议应标明来源,以便用户区分推断所得、搜索所得和手动提供的信息。
如果 docs/ 不存在,请在写入前创建该目录。如果用户取消,则不要写入文件——取消不会产生任何副作用。
编辑模式
当 docs/trd.md 已存在时运行。模式会自动检测——用户无需指定。目标是在不丢弃已有正确信息的前提下,让 TRD 保持同步:访谈只聚焦于已发生变化的部分,避免让用户重新确认未变更的内容。
第 1 步 — 读取当前 TRD
完整读取 docs/trd.md。如果文件存在但为空或已损坏(无法识别任何部分),则按创建模式处理,并告知用户。
第 2 步 — 重新分析和补充
按照创建模式(第 1 步)中的相同标准,重复自动分析。结果是一个“当前推断状态”,用于与现有 TRD 进行比较。
对于此次重新分析检测到的新外部依赖(项目中存在但当前 TRD 未记录),在向用户展示之前,应用创建模式第 2 步中的外部搜索补充流程。TRD 中已有记录的依赖无需重新搜索。
第 3 步 — 检测差异
比较 TRD 与推断状态,并对 6 个部分(技术栈、架构、非功能性需求、外部依赖、规范、全局决策)中的差异进行分类:
- (a) 项目中的变更未反映在 TRD 中 — 例如:框架变更、新增外部依赖、
docker-compose中新增服务、.env.example中新增环境变量 - (b) TRD 中的条目已无法在项目中得到验证 — 例如:依赖已移除、规范已弃用、外部服务已停用
- (c) 模糊区域 — 发现了不同之处,但无法确定这是真实变更还是解读差异
- (d) TRD 中缺少部分 — 例如:TRD 创建时还没有非功能性需求或外部依赖部分;此时应提供通过针对性访谈来补全该部分的选项
如果未发现任何差异,请告知用户 TRD 已同步,并结束流程,不做任何编辑。
第 4 步 — 针对性访谈
展示差异,并针对每一项提供以下决定选项:更新、保留或忽略。不要重新收集 TRD 中已有的正确信息——重点是差异,而不是完整重访。这可以保留用户已经确认的工作。
**ADR 处理方式:**默认保留 TRD 中对 ADR 的引用——未经明确确认,绝不移除。如果仓库中找不到被引用的 ADR,请将其标记为 *(未找到文件)*,并询问是否应移除该引用。状态为 已弃用 的 ADR 仍应使用 ~~标题~~ 列出。
步骤 5 — 预览与写入
在写入之前,展示已批准变更的摘要(已变更的章节与保留的章节)。只有在最后才会覆盖 TRD,并包含所有已批准的变更。
如果用户在任何时候取消,都不要写入——原文件保持不变。取消不会产生副作用:丢失之前的 TRD 要比之后重新访谈更糟。
Decision 模式
当用户要求记录一项技术决策时运行(“记录……的决策”、“创建 ADR”、“我们决定将 X 换成 Y”)。无论是否存在 TRD,ADR 都独立存放于 docs/adrs/。根据 references/template-adr.md 创建 ADR。
何时属于 ADR(何时不属于)
仅将持久、影响范围广且难以撤销的决策记录为 ADR——例如数据库选择、身份验证策略、架构模式、基础性库、API 约定。仅针对某项功能的局部决策不属于 ADR:如果难以撤销(新增依赖、数据模型、切片之间的接口),则应放在该切片的 PLAN 中,由 sdd-especificar 生成;如果可撤销(复用哪个 util、如何连接 endpoint),则无需记录。如果用户提出的是局部决策,应提醒用户并建议正确的处理方式,而不是创建 ADR。
步骤 1 — 编号
列出 docs/adrs/(如果目录不存在则创建)。下一个 ADR 的编号为现有最大编号 + 1,格式为 3 位数字的 NNN。如果还没有 ADR,则从 001 开始。
步骤 2 — 先生成草稿
根据用户描述的内容生成完整 ADR,无需长时间访谈。推断缺失的 Context、Alternativas Consideradas 和 Consequências,并为每项推断标注 *(premissa — confirme ou corrija)*。如果用户已经做出决定,初始 status 为 aceito;如果决策仍未确定,则为 proposto。
步骤 3 — 替代关系
如果此决策取代了先前的决策,则识别旧 ADR:
- 在新 ADR 中填写
supersedes: "NNN"。 - 在旧 ADR 中填写
superseded_by: "NNN",并将status改为obsoleto——这是对aceitoADR 唯一允许的修改。不要再编辑旧 ADR 的任何其他内容。
步骤 4 — 写入并在 TRD 中引用
- 写入
docs/adrs/NNN-slug.md。 - 如果存在
docs/trd.md,则在 “Decisões Globais” 表格中新增一行(#、标题、日期、状态、链接)。obsoletoADR 应以~~标题~~的形式呈现,绝不删除。 - 如果不存在
docs/trd.md,则告知用户:该 ADR 会在下次创建 TRD 时自动编入索引(创建模式中的 ADR 扫描会处理此事)。 - 建议提交:
docs(adr): adiciona ADR-NNN <slug>。
不可变性
aceito ADR 不可修改,除非在另一 ADR 取代它时修改 status。复审一项决策不应编辑 ADR,而应创建新的 ADR,并通过 supersedes 指向旧 ADR。这与 PRD concluido 的不可变性原则相同。
参考模板
references/template-trd.md— 生成的 TRD 的规范结构,包含 6 个必需章节。生成或编辑 TRD 章节时务必参考。references/template-adr.md— Decision 模式下生成的 ADR 的规范结构。创建 ADR 时务必参考。
不在范围内
此 skill 不会:
- 创建 PRD(由
escrever-prd负责) - 生成 SPEC、PLAN 或 TASKS(由
sdd-especificar负责) - 在 Decision 模式之外创建 ADR——在创建和编辑模式下,仅引用
docs/adrs/中已有的 ADR;创建 ADR 仅限 Decision 模式 - 做出业务决策——将信息缺口交由用户处理
- 在用户于写入前取消预览时编辑
docs/trd.md