关于 comet-open
Comet Phase 1: Open 是使用 OpenSpec 启动或恢复 Comet 变更的技能,指导需求澄清、工作区准备、初始变更结构创建和可恢复运行的初始化。
主要功能
- 01澄清需求
- 02准备隔离工作区
- 03检查 OpenSpec 兼容性
- 04创建变更工件
- 05初始化可恢复运行
适用场景
- 01启动新的 OpenSpec 变更
- 02明确范围和验收场景
- 03恢复现有变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rpamis/ comet --skill comet-open安装后在 Claude Code 中输入/comet-open确认已加载。
附带文件agents/openai.yamlreference/batch-changes.md
详细介绍
原文在翻译后有更新,译文可能不是最新。
Comet Phase 1:Open
开始或恢复之前,请阅读并遵循 comet-classic/reference/classic-layout.md。此文件中的所有 OpenSpec CLI 调用都必须使用适配器,所有路径都必须使用该协议绑定的 <classic-*> 逻辑根目录。
前置条件
- 当前没有进行中的变更,或用户希望创建新变更。
步骤
0. 设置输出语言
传递给 OpenSpec 的每个问题和工件生成请求都必须指定已解析的 Comet 工件语言,并使用 en 或 zh-CN 之类的规范化 ID。在 .comet.yaml 存在之前,先读取项目 .comet/config.yaml 中的 classic.language,然后读取全局 ~/.comet/config.yaml。初始化后,使用 comet state get <name> language。仅当未配置语言时,才回退到当前请求的语言。proposal.md、design.md 和 tasks.md 必须主要使用该语言。
0a. 绑定当前变更
恢复现有变更时,先检查 <classic-change-dir>/.comet.yaml:
- 如果文件存在且解析成功,运行
comet classic workspace resolve <change-name> --json,进入返回的projectRoot,并在其中选择该变更。 - 如果状态缺失,但变更目录有效,则使用选定的隔离模式准备工作区。进入返回的
projectRoot,运行comet state init <change-name> full --isolation <selected-isolation>,然后选择该变更。 - 如果状态格式错误,则停止并报告解析错误。只有通过版本控制、备份或可验证的工件手动修复后,才能恢复。不要使用
state set覆盖已损坏的状态。
comet classic workspace resolve <change-name> --json
# Enter the returned projectRoot
comet state select <change-name>
对于新变更,先初始化 .comet.yaml,然后立即运行上述选择命令。状态存在之前,不要手动写入选择信息。
0b. 在 Open 之前选择并准备工作区
创建 Classic 变更时,请阅读 comet-classic/reference/workspace.md。必须在创建 OpenSpec 工件或 .comet.yaml 之前选择工作区;不要将此步骤推迟到 Build 阶段。
- 如果用户明确要求并行工作,直接使用
worktree。必须在创建 OpenSpec 工件或状态之前准备好独立工作区。 - 如果未指定隔离方式,请遵循参考文档。需要选择时,列出可用的
current、branch和worktree选项;建议不能代替用户作出选择。 current和branch仍要求串行工作。不要将它们描述为适合并发会话的选项。
运行 OpenSpec new 之前,先准备工作区:
comet classic workspace prepare <name> --isolation <current|branch|worktree> --json
# Enter projectRoot; run subsequent OpenSpec/state commands and artifact writes there
prepare 命令会复用与分支匹配的已注册 worktree。如果分支仍然存在,但已注册的 worktree 被删除,则会重新创建该 worktree。只有在分支已重命名、被用于其他工作,或无法确认其归属时,才请求明确重新绑定。
0c. 检查 OpenSpec 兼容性
首次使用或上游安装发生变更后,运行一次此命令,并记录版本以便排查问题:
comet classic openspec -- --version
请检查实际能力,而不是根据版本推断兼容性。状态必须提供 changeRoot、applyRequires,以及每个制品的 requires、outputPath 和 status。指令必须提供可用的 resolvedOutputPath。已根据 OpenSpec 1.11.0/1.12.0 中的状态接口检查适配器;不保证兼容所有历史版本。如果命令不可用、以非零状态退出,或缺少必需能力,请停止并提供错误信息和升级指导。不要自动升级用户的环境。
创建后,comet state artifacts <name> --json 会检查路径、所有必需依赖项和实际文件。它会递归展开 applyRequires,并将 Classic 强制要求的 proposal/tasks 纳入完整依赖闭包。如果该闭包要求 design,即使指令称其为可选,也不得跳过;不在闭包内的 design 则不是强制项。
只有在请求不涉及行为规范变更、.openspec.yaml 明确设置 skip_specs: true,且不存在冲突的规范文件时,才能跳过规范。支持的角色为 proposal/specs/design/tasks。请报告不受支持的强制角色或输出模式,不要猜测如何处理。
1. 探索想法并明确需求
**现在必须执行:**使用 Skill 工具加载 openspec-explore 技能。不得跳过此步骤。
**调整外部 OpenSpec 指令:**仅使用其探索方法。不要遵循直接调用官方 CLI、切换到固定 cwd 或读取/写入硬编码 OpenSpec 目录的指令。每次 CLI 调用都使用 comet classic openspec -- <args...>,每个路径都使用本次调用绑定的 <classic-*> 根目录。
优先复用用户的 PRD、设计和已确认事实。找出以下方面的缺口,并整理成澄清摘要。只询问会改变范围、解决方案或验收标准的未知事项。如果信息已足够,则直接继续,不必再提问;澄清轮次没有最低要求。
- 目标:用户实际要解决的问题及期望结果。
- 非目标:此变更明确不包含的内容。
- 范围:包含和排除的模块、用户、平台或数据。
- 关键未知事项:尚未解决的假设、风险或依赖项。
- 验收场景草案:至少包括核心成功路径和重要边界情况。
摘要必须包含全部五个方面:目标、非目标、范围、关键未知事项和验收场景草案。
向用户提问前,请阅读 comet-classic/reference/decision-point.md。说明问题、建议及理由,并说明每个选项的影响;优先使用可用的 AskUserQuestion 工具。只询问当前存在的缺口。如果缺失的事实或材料不足以形成实际选项,请说明缺少的内容并提出请求。外部探索技能中的问题也必须遵循此流程;加载该技能并不意味着可以省略选项或代用户做决定。
请通过路径和相关章节引用完整 PRD,而不是复制其内容。不要重新确认已确定的事实;只澄清实际矛盾。OpenSpec 技能仍是必需依赖。探索结束后返回 Comet;外部技能不得自行进入设计、实施或归档阶段。探索获得批准并不取代 Open 的最终制品确认。
1a. 创建前确认是否拆分 PRD
对于大型 PRD、路线图、完整产品提案,或包含多个独立功能、模块、用户旅程或里程碑的澄清摘要,请在创建 OpenSpec 制品前评估是否需要拆分为多个变更。
根据已澄清的信息提出拆分方案。每个项目必须包括:
- 建议的变更名称。
- 目标和范围。
- 明确的非目标。
- 依赖项或建议的执行顺序。
- 核心验收场景。
符合以下任一情况时,建议拆分:
- PRD 包含多个可以独立设计、构建、验证和归档的功能。
- 涉及多个模块或用户旅程,且其中一部分可以独立发布。
- 具有不同的交付里程碑。
- 多个增量规范服务于彼此独立的目标,可以分别验收和发布。文档或任务的数量本身不能作为拆分依据。
- 某一部分失败或延迟时,不应阻碍其他部分继续推进。
如果建议拆分,请暂停在 comet-classic/reference/decision-point.md,等待用户选择。提供以下所有选项:
- “创建多个 OpenSpec 变更”:将每个建议项作为独立变更创建。
- “保留为一个变更”:继续使用单个变更,并在 proposal/design/tasks 中记录原因。
- “调整拆分方案”:询问用户希望如何调整,修改列表后再次征求确认。
每个获准项都必须通过 /comet-open 创建,不要直接使用 /opsx:new。/comet-open 会同时创建 OpenSpec 制品和 .comet.yaml,确保每项变更都遵循 Comet 状态机。
在用户选择如何拆分 PRD 之前,不要创建 proposal.md、design.md 或 tasks.md。如果用户选择创建多个变更,此次 /comet-open 调用仅处理拆分确认和排期,然后按获准顺序对每个项调用 /comet-open。
立即将已确认的批次保存到 .comet/batches/<batch-id>.json。使用稳定的 kebab-case batch-id。至少记录 version、原始目标摘要、创建时间、有序变更名称,以及每项的目标、范围、非目标、验收场景和 pending|open-complete|selected 状态。每创建或完成一项后,都要以原子方式更新文件。此列表用于跟踪批次顺序和进度;不能替代各项变更自己的 .comet.yaml。
为批次项调用 /comet-open 时,将其标记为“confirmed split item”,并传入其目标、范围、非目标和验收场景。除非该项仍明显包含多个独立功能,否则跳过 PRD 拆分评估。
不要自动将单个批次项从 Open 推进到 /comet-design。批次完成后,暂停并询问用户要先处理哪个变更。仅将所选变更推进到 /comet-design;其他变更保持未归档状态,供之后通过 /comet-classic 恢复。
**检查每个已完成的批次项;不得跳过:**所有项都完成 Open 后,对已确认列表中的每个 <name> 执行以下操作:
comet state check <name> design --json
此条目会验证所有必需的完整闭环、实际 OpenSpec 输出和 Comet 状态。不要重复进行单独的状态扫描。isComplete 仅用于诊断;可选制品不会阻碍进度。仅当检查失败时才查询状态,以定位缺失的依赖项或诊断报告的路径/能力错误。
如果任何拆分项未通过这些检查,不要宣布批次完成,也不要询问要先处理哪个变更。停止进一步推进,并从该变更第一个 ready 或 blocked 制品处恢复 /comet-open。如果 OpenSpec 检查通过,但 Comet 状态检查失败,应先修复 .comet.yaml 初始化或阶段,然后重新运行批次检查。
只有所有项都通过入口检查后,才能询问用户要先处理哪个变更。将用户选择的项在批次列表中标记为 selected,并仅将该变更推进到 /comet-design。其他变更保持未归档状态,供之后通过 /comet-classic 恢复。
恢复时,读取 .comet/batches/<batch-id>.json,然后对其中已创建且未归档的变更运行上述检查。不要重新创建已通过检查的项目。从 OpenSpec 返回的第一个 ready 工件继续处理失败的项目。根据已保存的列表创建其余项目。如果列表缺失或已损坏,请停止并让用户重建或确认该列表;不要根据目录名称推断原始批次。
1b. 总结需求并选择变更名称
创建工件前,将步骤 1 的调查结果整理为已确认的简报,内容包括目标、非目标、范围、关键未知事项和初步验收场景。拟定一个能准确描述该范围的英文 kebab-case 变更名称。
- 范围和名称明确时直接继续。 不要仅为征求对总结或名称的批准而暂停;最终审核会一并确认名称、范围和工件内容。
- 如果用户提供了名称,将其规范化为 kebab-case,并在进度更新中复述。只要规范化后含义不变,就无需再次确认。
- 重用已确认批次项目的总结和名称。只有范围发生变化或列表缺少必要信息时,才再次澄清。
- 只有在互斥的范围或目标变更选项仍未确定时,才根据
comet-classic/reference/decision-point.md提出联合问题。仅有命名偏好不是暂停的理由。
OpenSpec 变更名称必须使用英文 kebab-case:小写字母、数字和单个连字符。如果名称冲突但目标明确,请选择一个含义相同且不冲突的名称并继续。只有在无法判断应重用现有变更还是创建新变更时,才询问用户。
如果已确认的简报或变更身份仍不明确,请勿运行 comet classic openspec -- new change,也不要创建 proposal/design/tasks。请先补充缺失信息,或解决确实需要用户决定的问题,再进入步骤 2。
2. 创建变更结构并初始化状态
现在必须执行: 使用 Skill 工具加载 openspec-new-change 技能。不得跳过此步骤。
调整外部 OpenSpec 指引: 仅使用其变更创建方法。不得直接调用官方 CLI,不得采用固定的 cwd,也不得写入固定的 OpenSpec 根目录。创建、状态和指引操作均须通过 comet classic openspec -- <args...> 执行。所有路径均使用本次调用的逻辑根目录,包括 <classic-change-dir>。
在完整的 /comet-classic 流程中,默认不要加载 openspec-propose。仅在用户明确要求同时生成提案和工件时才加载它。
调整外部 OpenSpec 指引: openspec-propose 同样受这些限制:不得直接调用官方 CLI、使用固定的 cwd 或固定的物理 OpenSpec 路径。命令必须使用适配器,工件必须使用解析器提供的 <classic-*> 根目录。
按照已加载的技能创建变更的初始结构。如果步骤 1b 已生成明确的已确认简报,请覆盖其中“停止并等待用户指示”的行为,直接继续,无需重复提问。
使用已确认的简报填写工件。只有当简报仍存在会影响范围的歧义时,才返回技能中的问题。
创建初始结构后,立即初始化可恢复状态;不要等到所有工件都生成完毕(入口检查在步骤 3 中运行一次,而不是在此处运行):
comet state init <name> full --isolation <selected-isolation>
comet state select <name>
如果任何命令失败,请停止。然后运行一次 comet classic openspec --agent-json -- status --change "<name>" --json 并检查兼容性:
- 解析出的
changeRoot必须等于绑定的<classic-change-dir>。如果存在planningHome,它也必须位于仓库内。不支持外部制品路径。 artifacts必须包含 Classic 要求的 ID:proposal和tasks;并递归遵循它们的requires。applyRequires必须是可解析的制品 ID 列表。所有直接和传递依赖都必须存在,且不得形成循环。- 如果字段缺失、路径位于仓库之外或缺少必需 ID,立即停止。不要回退到猜测的模板。
检查通过后,根据 OpenSpec 返回的架构和依赖图生成所需制品。
在 Agent JSON 模式下,从 data.upstream.data 读取上游字段。仅执行 data.nextAction 返回的完整 argv 和 cwd。上游原始 nextSteps 仅用于诊断。
根据 OpenSpec 状态生成制品:
-
第一轮使用步骤 2 的兼容性检查状态,后续轮次使用前一次写入后刷新的状态。仅在恢复或外部制品发生变化时,重新运行
comet classic openspec --agent-json -- status --change "<name>" --json,并从data.upstream.data读取完整上游 JSON。 -
展开
applyRequires以及 proposal/tasks 的完整依赖闭包。所有项目均为done或合理地标记为skipped后,运行comet state artifacts <name> --json;仅当检查通过时退出循环。顶层 tasks 制品已完成,并不代表其依赖也已完成。isComplete仅用于诊断。 -
在状态为
ready的未完成制品中,优先处理能推进applyRequires依赖闭包的项目,并遵循 CLI 顺序。不要硬编码生成顺序,也不要假设架构中只有 proposal/design/tasks。 -
获取每个就绪
<artifact-id>的当前指令:comet classic openspec --agent-json -- instructions <artifact-id> --change "<name>" --json -
遵循返回的 JSON 指令:
- 读取
dependencies中所有已完成的依赖。 - 使用
template作为制品结构。 - 遵循
instruction。 - 将
context和rules作为约束;不要将它们复制到制品中。 - 写入
resolvedOutputPath。对于通配符输出,创建指令要求的所有实际文件。 - 确认 CLI 返回的实际输出文件存在且非空。
- 读取
-
创建每个制品后,使用
comet state artifacts <name> --json在本地验证依赖闭包(不启动 OpenSpec 子进程);仅当检查报告依赖缺失或顺序错误,或需要新的实时指令时,才刷新一次,然后重新检查路径和完整依赖闭包。不要重新生成状态为done的项目。仅处理闭包中新就绪的项目,不要处理无关的可选制品。
处理失败和受阻依赖: 如果 applyRequires 尚未完成,但没有必需依赖处于就绪状态,则报告相关的 blocked 制品及其 missingDeps,然后停止。不要猜测顺序或跳过依赖。如果适配器的 status / instructions 失败、返回无效 JSON、路径超出仓库范围,或缺少可用的 resolvedOutputPath,也应停止并报告 OpenSpec 错误。不要替换为硬编码的文档结构。
检查名称和范围: 使用步骤 1b 中解析出的英文 kebab-case 名称;不允许使用非 kebab-case 名称,包括中文名称。范围必须与解析出的简述和用户请求一致。不要自行扩大或缩小范围。
确认以下制品存在:
<classic-change-dir>/
├── .openspec.yaml
├── .comet.yaml
├── proposal.md # Why + What: problem, goal, scope
├── design.md # When required or useful; keep technical decisions here without duplicating them
└── tasks.md # Task checklist
3. 验证条目状态
检查状态是否已正确初始化:
comet state check <name> open
通过后继续执行步骤 4。若失败,脚本会报告具体原因。
恢复未完成的创建步骤: 可安全地重试未完成的操作。恢复时,按以下顺序处理状态,并保留已完成的工作:
- 如果状态缺失,请准备所选的隔离模式,进入返回的
projectRoot,并运行comet state init <name> full --isolation <selected-isolation>。若状态格式错误,请停止并修复,而不是覆盖。然后选择变更并运行comet state check <name> open。 - 运行
comet classic openspec --agent-json -- status --change "<name>" --json,并重新检查changeRoot、核心 ID、applyRequires、artifacts和missingDeps。 done:保留工件,不做更改,也不要重新生成。ready:使用comet classic openspec --agent-json -- instructions <artifact-id> --change "<name>" --json获取其说明,按说明编写工件,然后运行comet state artifacts <name> --json在本地验证闭包,而不是刷新状态。blocked:遵循missingDeps,先完成applyRequires闭包中的依赖项。每完成一个依赖项后,使用comet state artifacts <name> --json验证;只有在结果报告新问题时才刷新状态;不要直接生成受阻的工件。- 重复以上步骤,直到完整的必需闭包已完成或合理跳过,并且
comet state artifacts <name> --json验证通过。
如果必需依赖项无法推进,请列出相关受阻工件和 missingDeps,然后停止并报告。现有目录或三个固定文件不能代替 CLI 检查。反之,若可选工件不在 applyRequires 中,仅因 isComplete: false 不得阻碍实现。
4. 检查内容完整性
使用最近一次成功的 comet state artifacts <name> --json 结果检查必需工件。文件或架构发生变化后,应重新运行该命令。只要仍有任何问题,就不要进入步骤 5,也不要运行阶段守卫。
然后检查内容:提案必须涵盖问题、目标、范围和非目标;设计必须涵盖高层决策和数据流;任务必须明确。如果架构返回了规格或其他工件,也要根据其说明检查内容。提案、设计和任务均已存在,并不意味着其他必需内容可以省略。
5. 请用户确认工件
所有 OpenSpec 工件和内容检查完成后,根据 comet-classic/reference/decision-point.md 暂停并等待用户明确确认。确认前不要运行阶段守卫,也不要自动推进。
这次最终审查将同时确认变更名称、范围和工件内容。步骤 1b 不能替代此流程;在此之前也不要另行进行常规摘要或名称审批。
请提出单选问题,并提供以下摘要和两个选项:
摘要:
- 变更名称和已确定的简报: 最终名称、目标、非目标、范围和关键未知事项。
- proposal.md: 背景、目标和范围。
- 架构工件(如规格): 功能、要求和关键验收场景。
- design.md: 高层架构决策和解决方案选择。
- tasks.md: 任务数量和关键任务。
选项:
- “确认并继续”:工件符合预期;运行阶段守卫以推进。
- “调整工件”:收集所需更改并应用,然后再次请求确认。
收到确认后,完成退出条件。如果用户要求调整,请更新相关文件并再次获取确认。
退出条件
comet state artifacts <name> --json通过:所有必需的闭环步骤均已完成或合理跳过,且必需的输出非空。- 用户已确认所有 OpenSpec 工件内容均符合预期。
- **阶段守卫:**运行
comet guard <change-name> open --apply。只有所有检查均通过后,守卫才会推进阶段;它会独立于auto_transition更新phase。
退出前请使用 --apply。否则,.comet.yaml 会保持 phase: open,下一次入口检查将失败。
comet guard <change-name> open --apply
完整工作流会转入 phase: design;hotfix/tweak 预设会转入 phase: build。
继续下一阶段
遵循 comet-classic/reference/auto-transition.md 和成功结果中的 agent.continuation。当已有有效状态信息时,不要重复执行 next、select 或 check。只有在上下文丢失、外部状态发生变化,或较早的结果缺少相关信息时,才运行以下内容:
comet state next <change-name>
NEXT: auto:调用SKILL指定的技能以继续。NEXT: manual:不要调用下一项技能。遵循HINT,交还控制权,并在本次调用中结束,不要再提出确认问题。NEXT: done:工作流已完成。
阶段直接转入 build 后,hotfix/tweak 技能会自行控制后续流程。其 next 结果会指定相应的预设技能。