mcpField
P
prd-to-plan

prd-to-plan

github.com/semi-sentient开发637 次安装1 周前更新
代码仓库

关于 prd-to-plan

prd-to-plan 是面向编码 Agent 的技能,可将 PRD 转为分阶段的垂直切片实施计划,并输出到项目的 plans 目录。它还支持将计划关联到 GitHub issue,或在本地模式下工作。

主要功能

  1. 01按垂直切片拆分实施阶段
  2. 02记录跨阶段架构决策
  3. 03检查验收标准是否可验证
  4. 04将计划写入 Markdown 文件
  5. 05支持关联 GitHub issue

适用场景

  1. 01为新功能 PRD 制定实施路线
  2. 02把大型需求拆分为可审查阶段
  3. 03为编码 Agent 准备独立阶段任务

安装

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

$npx skills add https://github.com/semi-sentient/skills-workflow --skill prd-to-plan

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

附带文件references/i18n-phase.md

详细介绍

PRD 转计划

使用纵向切片(示踪弹)将 PRD 拆分为分阶段实施计划。输出为项目 plans 目录中的 Markdown 文件。

流程

1. 确定 PRD 来源和 GitHub 是否可用

确定 PRD 内容的来源,以及本次调用是否会发布到 GitHub。

步骤 1a — 检测 GitHub 是否可用(开销低,只运行一次):

  • git remote get-url origin — 如果没有输出,或 URL 不是 github.com,则 GitHub 集成不可用(纯本地模式)
  • 如果存在 GitHub 远程仓库,则运行 gh auth status — 如果未通过身份验证,则 GitHub 集成不可用

从远程 URL 中提取 <org>/<repo>,供后续使用。

步骤 1b — 按优先级确定 PRD 来源:

  1. 传递给此技能的显式 GitHub issue 参数(例如 #123 或 https://github.com/<org>/<repo>/issues/123)
  2. 上下文中的 GitHub issue URL,与当前仓库的远程仓库匹配,通过扫描对话检测
  3. 带有 `` 页脚的本地 PRD 文件 — 如果用户指定了本地 PRD 文件(或从最近的对话中可以判断文件位置,例如 write-a-prd 刚刚写入了文件),则读取该文件。如果包含页脚,则提取 N,并视同显式 GitHub 参数。这是 write-a-prd → prd-to-plan 在不同对话之间交接时无需用户手动复制 issue 编号的方式。
  4. 上下文中或本地不带页脚的 PRD 内容(纯本地模式)

如果用户传递了 --no-github(或等效选项),则完全跳过 GitHub,无论上下文如何都仅在本地模式下操作——包括忽略本地 PRD 文件中的任何页脚标记。

步骤 1c — 处理每种情况:

  • 存在显式参数,且 GitHub 可用:
    • 运行 gh issue view <n> --json number,title,url,updatedAt(不获取正文 — 避免 PRD 已在对话中时重复内容)。这也可作为预检,确认父 issue 存在。
    • 显示确认信息:Linking plan to #<n> '<title>' — last updated <updatedAt>. 被动显示时间戳;不要就此提示用户。
    • 如果 PRD 尚未出现在对话中,则获取完整正文:gh issue view <n> --json body,title,number,url
    • 如果对话中提到了此仓库的其他 issue 编号,则在继续前指出不匹配:You passed #<n> but I noticed #<m> earlier. Continue with #<n>?
  • 存在显式参数,但 GitHub 不可用: 明确报错。说明是缺少 gh、未通过身份验证,还是仓库不属于 GitHub。不要静默回退。
  • 检测到上下文中的 issue,且 GitHub 可用:
    • 单个匹配项:Detected GH issue #<n> '<title>' in this conversation. Link the plan as a sub-issue? (yes / specify different / skip GH)
    • 多个匹配项:列出它们,并询问选择哪一个(或输入 none)
    • 确认后,按用户传递了显式参数的情况继续
  • 检测到上下文中的 issue,但 GitHub 不可用: 静默跳过检测;仅在本地模式下操作
  • 检测到本地文件页脚,且 GitHub 可用: 按用户显式传递了页脚中的 issue 编号处理(同“存在显式参数,且 GitHub 可用”的情况)。通知用户:Detected GH issue #<n> from PRD footer — linking plan as a sub-issue. Use --no-github to disable.
  • 检测到本地文件页脚,但 GitHub 不可用: 明确报错 — PRD 声明已发布,但无法访问 GitHub;不要静默取消子 issue 关系。用户需要修复 gh 配置,或传递 --no-github 明确切换到本地模式。
  • 上下文中没有相关内容,且没有显式参数: 仅在本地模式下操作。如果对话中也看不到 PRD 内容,则请用户粘贴内容或提供文件位置。 功能名称(标准化)。 在本技能中,<feature name> 指去除前缀 PRD: 后的源标题(不区分大小写,并去除首尾空白)。源标题是 GH issue 标题(GH 模式),或本地 PRD 中的 # PRD: <Feature Name> 标题(纯本地模式)——write-a-prd 会为两者加上 PRD: 前缀,便于扫描。此此前缀不得出现在派生产物中:计划 slug(Step 7b)、计划标题(Step 7d 模板)或 Plan: <feature name> 子 issue 标题(Step 8b)——否则就会得到 Plan: PRD: … 和 prd-…-plan.md slug。仅在逐字引用实际 issue 的地方使用原始标题——上方的 Linking… / Detected… 确认消息,以及 Source PRD: 标题中的 ("Title") 部分。
2. 探索代码库

如果你尚未探索代码库,请进行探索,以了解当前架构、现有模式和集成层。

3. 确定持久的架构决策

拆分阶段之前,确定在整个实现过程中不太可能改变的高层决策:

  • 路由结构 / URL 模式
  • 数据库 schema 结构
  • 关键数据模型
  • 身份验证 / 授权方式
  • 第三方服务边界
  • i18n 命名空间和可复用键引用(见 Step 3.5)

将这些内容写入计划头部,以便每个阶段都能引用。

3.5. 评估 i18n 影响

决策关卡:

  • 如果 PRD 只涉及重构、测试、配置或其他不包含面向用户文案的变更,跳过此步骤。
  • 如果项目未使用 i18n,跳过此步骤。
  • 否则(PRD 引入或修改了面向用户的文案,且项目使用 i18n)→ 立即停止并阅读 references/i18n-phase.md。其中包含完整流程(发现配置 → 审核可复用键 → 列出新键 → 规划 Translations 阶段 → 在后续阶段接入),以及 Step 6 验证所用的验收信号。阅读之前不得继续 Step 4。
4. 起草纵向切片

将 PRD 拆分为示踪弹阶段。每个阶段都是一个贯穿所有集成层的精简纵向切片,必须端到端完成,而不是仅覆盖单个层的横向切片。

- 每个切片都要贯穿所有层(schema、API、UI、测试),交付一条精简但完整的路径 - 完成的切片应能独立演示或验证 - 优先选择多个精简切片,而不是少数几个厚重切片 - 省略各阶段间容易变化的实现细节(例如中间变量名、可能重构的内部状态结构、样式细节) - 务必包含有助于解决实现歧义且持久的实现细节(例如要使用的库或框架组件、应遵循的具体 API 模式、错误处理策略、序列化格式) - 务必包含持久的决策:路由路径、schema 结构、数据模型名称 #### 自主执行下的阶段规模

当计划由 run-plan 执行时,没有人会在阶段之间停下来查看应用,因此“可独立演示”并非阶段边界的价值所在。阶段边界带来四项价值,而且都不要求阶段本身可演示:审查范围(每次判定需要评估的标准更少)、重试影响范围(每次纠正过程中丢弃的工作更少)、提交粒度,以及上下文隔离(每个阶段都在全新的 Agent 窗口中运行,因此阶段越小,单个 Agent 累积的上下文就越少)。按以下两部分规则划分阶段:

  • 规模控制 — 限制阶段规模。 规划时可用标准数量作为代理指标:标准数达到两位数时,应视为需要拆分的信号。这只是一个方向性指标,并非硬性限制——审查成本随每次判定所需评估的标准数量增加,重试时会重新审查整个阶段,而固定的重试上限对 4 个标准的阶段来说较为宽裕,对 12 个标准的阶段来说却可能过于严格。如果源 PRD/issue 或 ADR 已经确定了阶段边界,则应优先遵循这一决定:将该决定记录在计划的架构决策中,并保持阶段完整,即使标准数超过十个也不例外——拆分若与既定决定相悖,就是一个问题,而非节省。
  • 切分位置 — 每个拆分后的阶段都必须保留审查者可以判定失败的标准。 审查关卡会审核验收标准,因此标准的质量决定了它能否发现问题。垂直切片通常能产出可判定失败的标准(“恰好有一个重叠分配时,工位下方会显示员工姓名”);水平分层则往往会产生轻易就能满足的标准(“客户端导出 getStationAssignments”)。但要求是可判定失败,而不是垂直切片。唯一明确可以不采用垂直切片的情况:纯机械性的阶段(本地化文件、代码生成),其标准仍可证伪——“en、es 和 hi 中均存在这九个键,且位于指定位置”“没有任何 es 值是英文”——这类阶段是安全的,因为审查关卡仍能判定其失败。依赖 shell 检查的标准必须注明运行目录:在子目录中运行相对于仓库根目录的路径规范,会像真正的零命中通过一样不输出任何内容,从而使关卡形同虚设。要求记录证据的标准必须指定审查者能够读取的位置(提交说明、已提交文件、已同步的计划 issue)——“在进度说明中”没有指定任何持久位置,审查关卡会将其判为 NOT MET。只有人类才能满足的标准必须以 Human verifies … 开头——第 6b 步的“标准可验证性”检查项会核查这三项。

缩小阶段规模并非没有代价:每个阶段都会增加固定开销——简报、启动一次审查、提交、交接。如果所有阶段都从不失败,拆分会增加总成本;只有在阶段需要纠正处理时,拆分的收益才会显现,而且预期缺陷率越高,收益越大。风险最高的工作应优先拆分。

不属于计划内容的事项

不要在计划中加入以下阶段或步骤:

  • 创建分支 — run-plan 会在开始时自动创建 plan/<slug> 工作分支
  • 每阶段提交 — run-plan 会在每个阶段结束后,按照 commit 技能的格式提交
  • 提交 PR — run-plan 会在运行结束时创建 PR,并链接计划子 issue 和父 PRD
  • 合并/部署流程 — 这些属于团队的发布流程,而非计划内容

计划描述的是工作(要构建什么、如何验证)。Git/GH 流程(分支、提交、PR)由 run-plan 统一处理。用户可以通过 --no-branch 或 --no-pr 选择跳过个别环节;计划无需针对这些覆盖选项调整——无论如何,计划都只描述工作。如果 PRD 要求合并后的验证或生产环境观察,应将其记录为描述_观察内容和决策_的阶段,而不是提交/PR 步骤。

跨阶段演进

当某个共享函数、组件或数据结构在一个阶段中引入,并在后续阶段中修改时,请明确记录其演进过程:

  • 在较早阶段:说明构建了什么,并注明后续阶段会扩展它
  • 在后续阶段:明确说明该阶段会修改较早阶段的实现,并描述修改前后的变化(例如:“修改第 2 阶段中的 resolveDefault(),使其在回退到硬编码默认值之前先检查缓存”)
  • 这样可以避免实现 Agent 从头重建,或对函数的当前状态感到困惑
向前兼容性

对于每个阶段,确定必须为后续阶段预先考虑的结构设计:

  • 后续阶段将填充的扩展点(例如:“Response DTO 包含一个空的 metadata 映射——第 4 阶段会在其中填充审计字段”)
  • 后续阶段将覆盖的抽象点(例如:“使用 resolveEndpoint(key) 函数解析路径,以便第 6 阶段可以换用特定租户的路径”)
  • 在该阶段的“要构建的内容”部分将这些内容明确记录为说明
5. 请用户评估

以编号列表的形式展示提议的阶段划分。对于每个阶段,展示:

  • 标题:简短的描述性名称
  • 涵盖的用户故事:说明该阶段对应 PRD 中的哪些用户故事(如果 PRD 按编号决策而非用户故事组织,请引用决策编号,并通过 PRD 覆盖关系将决策映射到各阶段)

询问用户:

  • 粒度是否合适?(太粗 / 太细)
  • 是否应合并某些阶段,或进一步拆分?

持续迭代,直到用户批准阶段划分。

6. 验证计划

写入文件前,请根据实际代码库验证计划,而不是依赖记忆。审阅者需要一份可供阅读的文档,因此首先将完整计划(使用步骤 7d 的模板)写入 plans 目录之外的临时草稿——在运行时确定临时位置,并按以下顺序检查:仓库自身说明要求使用的临时目录,然后是主机的临时目录,最后是 plans 目录的同级 scratch/ 目录(如果该位置在仓库内,使用 git check-ignore 验证 Git 会忽略它;如果未被忽略,请自行将其添加到 .git/info/exclude——切勿假定已有忽略规则),绝不能使用 plans 目录本身;该目录在步骤 7 中只接收获批的成果——并将临时草稿的路径交给审阅者,在简报中说明该临时位置是有意选择的,并非发现的问题。本步骤中的每项修正都应编辑草稿;步骤 7 会将获批的草稿复制到目标位置。这样可以避免计划错误最常见的来源:依据过时的记忆,而非真实文件。起草计划的 Agent 会以善意方式解读它,因为它知道每个阶段的意图;因此,只要主机条件允许,就应由拥有全新上下文窗口的独立审阅者来完成验证,而不是让作者重新阅读自己的内容。

步骤 6a — 选择验证模式(能力门槛):

  • 优先方式——独立审阅者。 如果宿主可以启动拥有独立上下文窗口的子 Agent(参考实现是 Claude Code 的 Task 工具,例如用于只读审阅的 Explore Agent),请委托其中一个进行验证。向它提供计划和 Step 6b 检查清单,但不要提供你制定计划的理由——它必须从头阅读引用的文件,并根据证据判断每项主张。审阅者只报告发现的问题,不进行编辑。 对于大型计划,你可以安排 2–3 名审阅者并行审查(例如,一名检查源文件和可行性准确性,一名检查阶段间的一致性及 PRD 覆盖情况,一名检查 i18n)——人数宜少;大多数检查成本很低。然后由你(作者)落实修正。
  • 备用方式——对抗式自我审阅。 如果宿主无法启动子 Agent,就在单独的一轮中,将 Step 6b 检查清单作为明确的 红队 审查自行执行:在实际文件证明情况并非如此之前,假定每个阶段都有误。这种方式仍会受到作者偏见影响,因此弱于独立审阅者,但远胜于宽容地重读一遍。

**无论采用哪种方式,**现在都要从磁盘重新阅读各阶段「要构建的内容」部分引用的每个源文件,而不是依赖你之前的摘要。

Step 6b——验证检查清单(由审阅者执行;作者修复发现的问题):

  • 源文件准确性 — 文件路径确实存在。函数签名与计划描述一致。Provider/组件嵌套层级准确。接口和类型与计划声称要扩展的内容一致。
  • 架构可行性 — 对于每个阶段,组件都确实能够访问其被描述为会使用的上下文/钩子/函数。检查 Provider 嵌套、导入路径和模块边界。
  • 跨阶段连贯性 — 对于每个修改早期阶段内容的阶段,都明确记录了修改前→修改后的变化;早期阶段的测试不会因后续更改而悄然失效;共享接口的演进保持一致。
  • 决策完整性 — 不得出现任何「二选一」、「或者另选方案」、「如果 > N 行」或其他未解决的表述。每项都必须明确为单一、具指示性的决策。计划要敲定决策,而不是罗列选项。
  • PRD 覆盖度 — PRD 中的每个用户故事至少对应一个阶段。PRD 中的每项测试决策都对应一个 TDD 切片。
  • 标准可验证性 — run-plan 的 Review Agent 必须能够仅凭仓库内容检查每条验收标准。包含三个子检查:(1)可执行性:从验收标准指定的目录运行其中列出的每条只读 shell 命令,并报告其当前返回结果与计划要求在该阶段完成后返回的结果;已经通过的命令无法证明任何内容,无法在正确实现上通过的命令会导致执行 Agent 修改有效代码,而在当前主机 shell(BSD 与 GNU grep/sed/regcomp;\s 并非通用写法)上无效的命令会造成无法区分的静默通过。(2)证据位置:要求记录输出的标准必须指定审核者可读取的位置——阶段提交说明、已提交文件或已同步的计划 issue;绝不能写「进度说明」、「摘要」或对话:这些内容并非持久记录,审核者也无法查看。(3)执行者:只有人类才能满足的标准(例如执行操作、检查控制台、观察实时流量)必须以 Human verifies …/Human confirms … 开头,以便执行技能的人类关卡规则能够通过机械方式识别;在包含 **Known risk**: human action 行的阶段中,每一条此类标准都必须标注,而不只是其中一条。
  • i18n 完整性 — 如果 PRD 包含面向用户的字符串,且项目使用 i18n,则验证计划符合 references/i18n-phase.md 中的验收信号:Phase 1 是 Translations 阶段,架构决策列出 i18n 命名空间和可复用键,后续阶段不修改翻译文件,非默认语言区域有实际翻译。如有任何一项标准未通过,则返回 Step 3.5 重新修改。

Step 6c — 信心评分(必须由作者以外的人独立完成)

为每个阶段评定 0–10 分,表示 AI 编码 Agent 仅凭计划就能正确实现该阶段的可能性。评分必须由执行验证的人给出,而不是计划作者——作者给自己的计划打分毫无参考价值。在独立审核模式下,由审核者给出评分;在备用模式下,将评分视为自查清单提示,并以 Step 6d 的用户批准作为真正的关卡。

对于任何低于 9 分的评分,审核者还必须对差距进行分类:规格缺口(可通过在计划中补充细节来解决)或不可消除的风险(无论在计划中补充多少细节都无法消除)。不可消除的风险必须属于以下列出的命名原因之一:

  • 该阶段需要执行编码 Agent 无法完成的人工操作,无论是验证还是设置(目视检查、实体硬件操作、在第三方控制面板中进行配置)。
  • 该阶段依赖于实施前无法获知的外部系统行为(未记录的 API 响应、生产数据的形态)。
  • 该阶段剩余的不确定性存在于运行时行为中,只有针对真实状态执行变更才能观察到(针对真实数据执行迁移、并发负载下的行为)——而非代码应如何编写。

只有在没有任何待处理的第 6b 步问题时,才能将风险归类为不可消除;规范含糊通常会以第 6b 步问题的形式显现,因此,清单无问题是判断“已无可修复之处”的实际标准(下方的反事实评分可兜底第 6b 步遗漏的问题)。审查者还必须报告:如果解决了所列原因,该阶段可获得的反事实评分。只有当反事实评分达到 9 分或以上,且实际评分达到 5 分或以上时,才适用例外。低于 5 分时,不可使用不可消除风险例外——返回第 5 步,将有风险的工作拆分出来,或为其设置检查点,使其成为独立的精简阶段(该下限仅适用于例外:若低于 5 分的阶段被归类为规范缺口,应按下一段进行修复,绝不能仅因评分低而拆分);若某阶段本身已是用于隔离风险的最小切片,且验收标准中包含人工检查点,则不受此下限约束(否则拆分会陷入无限循环)。在回退模式下,归类和评分一样,都是作者自行给出的判断;在第 6d 步表格中将此类行标注为自行归类,以便用户在知情的情况下批准。

标记所有低于 9 分的阶段。在继续之前,修复第 6b 步清单中的所有问题。对于被标记为规范缺口的阶段,补充具体的实施细节(代码片段、API 配置、准确的函数签名),直到评分达到 9 分或以上,或剩余差距完全由某个列明的原因造成。对任何被标记的阶段应用修复后,按第 6a 步所用的相同模式重新运行验证;第 6d 步中列出的评分和归类必须来自此次重新验证——在独立模式下,绝不能来自作者;在回退模式下,必须来自新一轮红队审查,而不能沿用修复前的结果。重新验证可以仅针对修复涉及的阶段(以及任何跨阶段引用发生变化的阶段),也可以针对一组命名的修复或单个问题(适用于修复涉及多个阶段的情况)——无论哪种方式,任务说明都必须写明范围;随后,第 6d 步表格必须为每个评分标注产生该评分的轮次,从而清楚显示未变阶段的旧评分早于当前评分,绝不将其误作当前评分。 收敛。 每轮的评审简报(包括第 1 轮)都会要求评审者将每项发现归类为 设计(第 6b 步中除标准可验证性之外的任何项目)或 标准(标准可验证性),并将每项设计发现评为 严重(按当前阶段内容会构建出错误的东西,或无法构建)、主要(执行 Agent 会停滞或只能猜测)或 次要(其他情况)。如果某轮的设计发现中没有严重或主要问题,则该轮已收敛,无论评分如何:修复其余发现,仅针对改动后的标准重新运行标准可验证性检查,然后进入第 6d 步——表格会列出收敛后的修复内容;对于评分仍低于 9 的阶段,表格会列出其评分,并注明“没有尚未解决的主要设计问题”;是否发布由用户决定。零发现不是门槛:对抗式评审者每轮都会返回一些内容,而修复轮也可能引入下一轮发现——退出条件是所有发现均为次要,而不是没有发现。未收敛的轮次按常规循环处理:作者修复其发现,评审者按照第 6c 步重新评审,其中的范围规则保持不变;收敛只决定是否跳过设计复审,不会改变由谁执行什么操作。绝不展示作者调整后的评分:无论之后作者完成了多少项修复,第 6d 步的表格都必须列出每个阶段最近一次由评审者给出的评分,并标明轮次。若发现指出现有标准存在缺陷,应通过改写或删除该标准来回应,绝不能在旁边再添加一条;若发现指出缺少必要标准,则属于覆盖缺口,可以合理地新增一条。在验证过程中新增标准,正是阶段达到分割信号阈值并重新启动循环的方式——在生产中,有两轮都在六轮中的最后两轮以这种方式完成。绝不要为了抬高评分而给阶段填入编造的细节;虚构的片段看起来像权威内容,比明确标记阶段存在问题更糟。

按例外情况接受的阶段必须将风险写入计划文件:在第 7d 步中,为该阶段添加一行 **Known risk**: <named cause>;若风险由人工操作导致,还要添加对应的验收标准(例如 - [ ] Human verifies <X>)——执行 Agent 只会阅读计划,因此只存在于本次对话中的风险,他们永远看不到。

第 6d 步——展示验证结果——向用户展示一张汇总表,列出每个阶段的置信度评分(0–10)、发现的任何问题,以及为解决问题所做的更改。如果验证改动了用户在第 5 步批准的结构(合并或拆分了阶段),表格应展示新结构,并说明改动内容及原因——无需重新征求第 5 步的批准;本次批准涵盖这些改动。对于因不可消除的风险例外而展示的任何评分低于 9 的阶段,表格必须说明具体原因(在回退模式下标明该原因由自身分类),以确保用户是在明确接受该风险,而非忽视它。未获得用户明确批准之前,绝不要进入第 7 步。如果用户要求修改,则进行修订、重新验证(模式与上文相同),并再次展示。重复此过程,直至获得批准。

7. 编写计划文件

前提条件:必须先向用户展示第 6 步的验证结果,并获得明确批准,之后才能编写计划。如果第 6 步尚未完成并获批,请现在返回并完成该步骤。

第 7a 步 — 确定计划目录,按以下优先级处理:

  1. 如果 .agents/plans/ 存在,则使用它
  2. 否则,如果 .claude/plans/ 存在,则使用它
  3. 否则,如果 .agents/ 存在,则创建 .agents/plans/ 并使用它
  4. 否则,如果 .claude/ 存在,则创建 .claude/plans/ 并使用它
  5. 否则,创建 .plans/ 并使用它

第 7b 步 — 派生计划 slug:

slugify 规则(与 write-a-prd 第 6a 步共用):

  1. 转为小写
  2. 将空格替换为连字符
  3. 删除所有非字母数字字符和非连字符
  4. 将连续的多个连字符合并为一个;去除首尾连字符
  • 如果正在使用本地 PRD 文件(例如 .agents/plans/mui-v9-migration-prd.md),则通过替换后缀来配对 slug:mui-v9-migration-plan.md
  • 否则,将 GH issue 标题中的前缀 PRD: 去掉(即第 1c 步的功能名称规则),然后按上述规则生成 slug:"PRD: MUI v9 Migration" → "MUI v9 Migration" → mui-v9-migration-plan.md
  • 在第 6d 步的审批消息中说明生成的文件名;用户的批准也涵盖该文件名(无需单独确认)

第 7c 步 — 再次调用检测(写入前执行):

检查现有状态:

  • 目标计划文件是否存在于计算出的路径?
  • 如果涉及 GH:父 issue 下是否存在标题为 Plan: <feature name> 的子 issue?优先读取现有本地文件中的 `` 页脚(比按标题匹配更可靠)。否则,查询 gh api /repos/<org>/<repo>/issues/<parent>/sub_issues 并按标题匹配。

根据状态选择分支:

本地文件子 issue提示
否否正常继续
是否Plan file exists. Overwrite (regenerate) / re-publish existing file as sub-issue / cancel?
是是Plan file and sub-issue #N both exist. Regenerate file / update sub-issue body / cancel?
否是Sub-issue #N exists but no local file. Fetch its body as the local file / regenerate from scratch / cancel?

如果用户选择了仅发布或仅更新的路径,则跳过下方的文件写入,直接跳到第 8 步并使用现有文件。否则继续。

第 7d 步 — 使用以下模板编写计划。

Source PRD: 标题有两种形式——不可混用:

  • 涉及 GH: > Source PRD: #123 — https://github.com/<org>/<repo>/issues/123 ("Title")
  • 纯本地: > Source PRD: .agents/plans/<slug>-prd.md

涉及 GH issue 时,省略任何本地 PRD 文件引用——GH issue 是规范来源,本地 PRD 文件通常尚未提交(在 GitHub 上阅读计划的人看到本地路径可能会感到困惑)。

# Plan:

Source PRD: <以下形式之一:>

  • 涉及 GH:#123 — https://github.com/<org>/<repo>/issues/123 ("Title")
  • 纯本地:.agents/plans/<slug>-prd.md

架构决策

适用于所有阶段的长期决策:

  • Routes:...
  • Schema:...
  • Key models:...
  • i18n:使用的命名空间/范围、可复用的键引用(来自第 3.5 步;如果没有面向用户的字符串或不涉及 i18n,则省略)
  • (根据需要添加/删除章节)

阶段 1:<标题>

用户故事:<来自 PRD 的列表>

已知风险:<第 6c 步中列出的原因——仅适用于因不可消除风险例外而被接受且得分低于 9 的阶段;其他情况省略此行>

要构建的内容

简要描述此垂直切片。描述端到端行为,而不是逐层说明实现。

验收标准
  • 标准 1
  • 标准 2
  • 标准 3

阶段 2:<标题>

用户故事:<来自 PRD 的列表>

要构建的内容

...

验收标准
  • ...

8. 发布到 GitHub(仅当涉及 GH 时)

如果在仅本地模式下操作,则完全跳过此步骤。

步骤 8 — 确定操作,根据步骤 7c 的处理结果:

  • 创建 — 不存在现有子议题(首次发布,或重新调用矩阵中的“重新发布现有文件”)。遵循步骤 8a–8e。
  • 更新 — 应原地更新现有子议题(来自重新调用矩阵中的“更新子议题正文”分支)。跳过 8b–8e,仅遵循步骤 8f。

步骤 8a — 确认环节:

  • 创建路径:Ready to create sub-issue under #<parent> from <path>. Review the file (and edit if needed), then reply 'create' to proceed, or 'cancel' to stop.
  • 更新路径:Ready to update existing sub-issue #<n> from <path>. Review the file (and edit if needed), then reply 'update' to proceed, or 'cancel' to stop.

等待明确确认。用户可以在确认前编辑文件。

步骤 8b — 创建子议题:

首先确保存在 plan 标签,因为如果标签不存在,gh issue create --label plan 会因 HTTP 422 而失败:

gh label create plan \
  --color bfd4f2 \
  --description "Phased implementation steps and technical rollout details" \
  2>/dev/null || true

此操作具有幂等性:如果标签已存在,gh label create 会报错,而 2>/dev/null || true 会忽略该错误,因此已有的 plan 标签会保持不变。不要添加 --force — 这会覆盖现有标签的颜色和描述。如果此命令因真实原因(身份验证、网络)失败,下面的 gh issue create 会显示错误。然后创建子议题:

gh issue create \
  --title "Plan: <feature name>" \
  --body-file <path> \
  --label plan

同时获取新议题编号(用于显示)和议题的整数数据库 ID(用于步骤 8c 中的关联调用)。REST sub_issues 端点需要整数数据库 ID,而不是 GraphQL 节点 ID — 传入节点 ID 会返回 HTTP 422 is not of type 'integer'。使用以下命令获取:

CHILD_DB_ID=$(gh api /repos/<org>/<repo>/issues/<child_number> -q .id)

不要使用 gh issue view <n> --json id — 它返回 GraphQL 节点 ID(以 I_kw… 开头的字符串),端点会拒绝该 ID。

步骤 8c — 关联子议题:

gh 2.88.1 没有 --parent 标志,也没有 sub-issue 子命令。请使用 REST API。注意 -F(大写)标志 — gh api 会将 -f 的值作为字符串发送,但 sub_issue_id 必须是数字:

gh api --method POST /repos/<org>/<repo>/issues/<parent>/sub_issues \
  -F sub_issue_id=<child_db_id>

失败时最多重试 3 次,并使用退避间隔:250ms、1s、3s(大多数故障是临时的速率限制或最终一致性问题)。

步骤 8d — 成功时:

  • 将 `` 作为页脚追加到本地计划文件
  • 向用户报告子议题 URL

步骤 8e — 故障处理:

  • 创建失败(步骤 8b):本地文件完好无损。原样报告错误,并告知用户重新运行 /prd-to-plan #<parent> 以重试 — 步骤 7c 中的重新调用矩阵会检测到现有文件,并提供仅发布路径。

  • 重试后关联失败(步骤 8c):子议题已创建,但没有父级链接(即孤立议题)。不要自动删除。报告部分完成状态,并提供准确的修复命令:

    Plan written to <path>.
    Sub-issue #<n> created: <url>
    Failed to attach as sub-issue of #<parent>: <error>
    
    To fix the relationship manually:
      CHILD_DB_ID=$(gh api /repos/<org>/<repo>/issues/<n> -q .id)
      gh api --method POST /repos/<org>/<repo>/issues/<parent>/sub_issues \
        -F sub_issue_id="$CHILD_DB_ID"
    
    To start over: gh issue delete <n>, then re-run /prd-to-plan #<parent>.
    

步骤 8f — 更新路径(用户在步骤 7c 的重新调用矩阵中选择“更新子议题正文”时):

不执行创建和关联,而是运行:

gh issue edit <n> --body-file <path>

此操作会整体替换正文,同时保留议题编号、评论历史和子议题关系。不会添加变更日志前言 — 本地文件是唯一真实来源。

文件中已有 `` 页脚,这是首次创建时添加的;不要重复追加。成功后,只需向用户报告子议题 URL。

评论

支持 Markdown