mcpField
D
decisions-to-specs

decisions-to-specs

github.com/mtngtools开发045 次安装3 周前更新
代码仓库

关于 decisions-to-specs

decisions-to-specs 是一项工作流技能,用于将已解决的 GitHub 决策 issue 整理为仓库中的持久规格文件。它协助把决策分配到现有规格、新规格或 ADR,并在专用 worktree 中提交更改、创建 PR,同时将讨论记录与规格分开管理。

主要功能

  1. 01将决策分配到现有规格、新规格或 ADR
  2. 02写入前确认文件目标位置
  3. 03在专用 worktree 中修改仓库
  4. 04提交更改并创建拉取请求
  5. 05为源 issue 标记已取代
  6. 06在地图中更新规格交接信息

适用场景

  1. 01将已解决的 wayfinder issue 转为仓库规格
  2. 02避免重复并更新现有规格
  3. 03将复杂权衡记录为 ADR
  4. 04为后续生成工单准备规格

安装

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

$npx skills add https://github.com/mtngtools/agents --skill decisions-to-specs

安装后在 Claude Code 中输入/decisions-to-specs确认已加载。

详细介绍

决策 → 规格说明

仅限人工操作。 只有在人类明确点名要求时才启动此流程。如果你是从另一个技能来到这里,请停止,并在执行任何步骤前取得明确确认。

/wayfinder 将决策记录为 GitHub issue——记录当时的对话。这些 issue 是记录,而非决策的归属之处。此技能将 wayfinder 地图中的已解决决策落实为仓库中的持久规格说明文件,让下一步 /specs-to-tickets 有具体内容可供拆分。

从 GitHub 读取决策;将规格说明写入仓库。这两个界面有意保持分离(参见分离界面)。此技能只是桥梁——也仅仅是桥梁——绝不会创建 issue,也不会把规格说明移到跟踪器上。

在独立工作树中写入仓库。 其他会话共享主检出目录,而此技能会编辑整个目录树中的规格说明。在共享检出目录中工作,会将只写了一半的规格说明放进别人的构建中,或在别人工作时切换分支。以下所有仓库写入操作,都在此技能创建的独立工作树和专属分支中进行——参见步骤 4。步骤 1–3 只读取 GitHub 和目录树,可在任何位置安全执行。

落实决策后,其票据即被取代。 issue 是某次对话的快照;此后,决策归属于规格说明,后续决策、评审和实现只会完善规格说明。因此,几个月后再读决策票据时,它很可能已经过时,所以步骤 8 会在每张票据上添加指向对应规格说明的已取代横幅。issue 保持关闭状态,作为决策依据的追溯记录;/specs-to-tickets 会从规格说明中拆分出实现票据。

审批记录在跟踪器上,而不是规格说明中。 如果人类在此技能运行期间确定了某事项——例如需要审核的名称、规格说明的存放位置,或决定舍弃某项内容——请遵循 approval-policy 技能,了解应将记录写在哪里。规格说明保留由此产生的规则;谁批准、何时批准,以及该决策取代了什么,属于决策票据或地图。ADR 的备选方案讨论部分是目录树中唯一记录备选方案的地方,且只将其作为决策记录,而不记录对话过程。

流程

1. 加载地图及其决策

根据参数解析地图(issue URL 或编号)。如果未提供,则查找标有 wayfinder:map 的开放 issue。阅读其正文中的 Destination 和 Decisions so far。对于列出的每项决策,获取其子票据,并阅读 /wayfinder 在关闭时记录的答案——即解决说明。

完成标准: 已掌握 Decisions-so-far 中每项已解决决策的答案。没有持久影响的决策(死胡同、明确的“无需更改”)应附注后舍弃,而不是强行写入规格说明。

2. 梳理现有规格说明

开始写入前,先了解规格说明已有的存放位置,确保决策能够更新现有内容,而非重复创建:

  • 软件包/程序集的 spec/ 文件夹(以及任何位于更靠近代码位置的规格说明)
  • 根目录下的 spec/——跨领域规格说明
  • spec/adr/——现有 ADR(ADR 文件夹是 spec/ 文件夹的子文件夹,位于负责该决策的 spec/ 作用域中)

阅读 CONTEXT.md 以及涉及这些决策影响范围的任何 ADR。撰写所有内容时使用词汇表中的术语;如果某项决策与 ADR 冲突,应明确指出,而不是悄悄覆盖。

完成标准: 对于每项决策,都能指出对应的规格说明文件,或说明目前尚无此文件。

3. 为每项决策确定去向——写入前确认

应用归属规则,为每项决策确定归属:要更新的现有规范、要新建的规范,或 ADR。“如果合适,就放在离代码更近的地方”需要斟酌判断——请完整列出路由表(决策 → 目标文件 → 新建/更新),并在写入任何文件之前征得用户确认。

**完成标准:**用户已批准每项决策的目标。

4. 写入前先切换到 worktree

从这里开始,所有会修改仓库的操作都必须在此技能专属的 worktree 中进行,该 worktree 需从远程仓库全新创建——绝不可在主检出目录中操作,也绝不可直接操作 main:

git fetch origin
git worktree add <worktree-path> -b docs/specs-<map-number> origin/main

将其放在仓库内,而不是旁边,并以地图命名。 将会话移到项目外的目录,通常需要人类单独批准,这与任何工具权限都无关,只会多出一道提示。在工作目录内使用路径即可完全避免此事。遵循仓库现有的分支和 worktree 命名方式,并以地图命名二者,以便清楚识别其归属。

如果你使用 Claude Code——使用 .claude/worktrees/specs-<map-number>,即该运行环境专用的 worktree 目录,这样就无需信任任何新路径。使用 EnterWorktree 并传入 path 参数进入该目录;这要求该 worktree 已出现在 git worktree list 中,因此要按上述顺序操作。

其他 Agent——使用工具已忽略的仓库本地目录;.worktrees/specs-<map-number> 是安全的默认选项,而 .git/info/exclude 会将其隐藏,无需修改受跟踪的 .gitignore。然后,通过运行环境提供的任意机制,将该目录设为下文所有写入操作的工作目录。如果无法切换目录,请显式传入路径(git -C <worktree-path> …),以免误写入主检出目录。

如果获取远程内容后,基线已超出你在步骤 2 中阅读的版本,请在此重新阅读规范全貌——你实际写入的是 worktree,而不是主检出目录。

有些运行环境会限制在 worktree 中使用 shell 重定向。如果 heredoc 或 > 被拒绝,请改用文件写入工具和单一用途的简单命令,不要与限制较劲。

**完成标准:**会话位于新分支上的干净 worktree 中,从这里开始的所有写入都落在该目录中。

5. 编写和更新
  • **更新现有规范:**将决策融入相关章节。不要复述对话——问题单记录原因,规范记录已确定的决策。
  • **新建规范:**采用新规范结构,以便 /to-tickets 以相同方式处理。
  • **ADR:**采用 ADR 结构。

每项决策都必须链接回其来源 GitHub 问题单——规范说明的是 做什么,问题单说明的是 为什么做出该决定。

**完成标准:**步骤 3 中路由的每项决策都已反映在 worktree 的文件中。

6. 使用 /concise-copy 精简内容

对你修改的每个文件运行 /concise-copy。规范会被反复阅读,因此要精简篇幅。

7. 提交规格并创建 PR

规格只存在于当前会话可见的工作树中时,还不能算定稿。使用 /draft-commit-message 起草提交消息;提交规范由它负责——请遵循它的要求,不要在此重复其格式。

提供它无法自行判断的信息:涉及哪些议题,以及每个议题与本次提交的关系。

  • 映射议题是这项工作的归属工单。
  • 决策议题是相关文件的详细依据。
  • 不要关闭其中任何议题。 /wayfinder 已在相关讨论结束时关闭决策议题,而映射议题会保持开放,直到 /specs-to-tickets 将这些规格拆分为工单。

然后在工作树中提交,推送分支,并针对 main 创建 PR。

此技能绝不执行合并。 /squash-merge-and-clean-up 会合并 PR 并移除分支和工作树;在它运行前,请保留两者。

**完成条件:**第 5 步写入的每个文件都已提交到此技能的分支,且 PR 已创建。

8. 将每个决策工单标记为已被取代

返回每个为规格提供依据的决策议题,并在其正文开头添加以下横幅;如果重新运行,则替换已有横幅:

> **Superseded by spec — do not build from this ticket.**
> This decision now lives in `src/<Package>/spec/<feature>.md`, which is the source of truth and has almost certainly moved on since this was written. Below is *why* the decision was made; build from the spec.

列出该决策议题所支撑的每个规格。第 1 步中被舍弃的决策不添加横幅——没有内容取代它。

**完成条件:**第 3 步中分派的每个决策议题都带有横幅,并列出其规格文件。

9. 更新映射议题,然后汇报

将工作概述写回映射议题正文中的 ## Specs settled 标题下(参见约定)。这是下一步 /specs-to-tickets 将读取的持久指引;映射议题仍是展示工作进展唯一的地方。

然后向用户汇报:内容写入了哪些位置、规格所在的 PR、哪些决策议题已添加标记,以及 PR 合并后接下来要运行 /specs-to-tickets <map>。

**完成条件:**映射议题中包含 ## Specs settled 部分,并列出第 5 步写入的每个文件。

映射议题的 Specs-settled 部分

交接给 /specs-to-tickets 的内容。将其写入映射议题正文(如果没有该标题则新建;重新运行时则更新)。每个规格文件占一行——包含路径、处置方式,以及为其提供依据的决策议题:

## Specs settled

- `src/<Package>/spec/<feature>.md` — new — decisions: #12, #15
- `spec/<cross-cutting>.md` — updated — decisions: #13
- `src/<Package>/spec/adr/0003-<slug>.md` — ADR — decision: #14

处置方式为 new、updated 或 ADR。ADR 行也要记录,但需标明,以便下一步知道不要将其拆分为工单。

文件放置规则(局部性阶梯)

优先选择能够完整涵盖该决策的最小作用域:

  1. 包/程序集的 spec/——决策仅影响一个包。若更适合,也可以放得更靠近代码(例如模块旁边)。
  2. 根目录的 spec/——跨领域:涉及多个包,或影响系统整体结构。
  3. spec/adr/(ADR)——当决策难以撤销、缺少背景信息时出人意料,且源于真实的权衡取舍(三项都符合 Matt 的 ADR 标准)。少于三项则不是 ADR。ADR 文件夹嵌套在与决策作用域相同的 spec/ 下:包级 ADR 放在 <package>/spec/adr/,跨领域 ADR 放在根目录的 spec/adr/。

**规格与 ADR:**规格描述要构建什么;ADR 记录某项决策及其依据。同一个决策可以同时产出两者——ADR 说明“为什么”,规格说明“是什么”——但只有在两者各自都足够重要时才拆分。

新规格的结构

仿照 /to-spec 的模板,以便 /to-tickets 能以相同方式读取。删去决策衍生规格不需要的部分:

  • 问题陈述——从用户角度描述
  • 解决方案——从用户角度描述
  • 用户故事——As an <actor>, I want <feature>, so that <benefit>
  • 实现决策——模块、接口、契约、架构(不含文件路径或代码)
  • 测试决策——边界,以及良好测试应覆盖的内容
  • 范围之外

ADR 结构

遵循套件的 ADR 格式:在所属范围内使用带编号的 spec/adr/NNNN-slug.md(扫描该文件夹,找到最大编号并递增)。标题 + 1–3 句话:背景、决策及原因。只有确有必要时才添加 Status / Consequences。ADR 可以只有一段——它的价值在于记录 做出了 什么决策,以及 原因。

分离界面

GitHub 用于保存讨论(wayfinder 映射 + 决策 issue),之后也用于保存实现任务。仓库用于保存规范。将两者分开正是目的:记录不会让仓库变得臃肿,规范也不会埋没在 issue 跟踪器中。

在流程中的位置

/wayfinder → GitHub 决策 issue(已关闭、注明理由、标记为已取代)→ /decisions-to-specs → 工作树分支上的仓库规范文件,作为 PR 提交(并在映射中添加 ## Specs settled)→ /squash-merge-and-clean-up → /specs-to-tickets → /to-tickets → GitHub 实现任务(新建,与决策 issue 相互独立)→ /implement。

可选:将最后一步写入 wayfinder 映射的 ## Notes——"路线明确后,运行 /decisions-to-specs"——或者在决策积累到足以敲定时手动运行。

评论

支持 Markdown