--- name: comet-archive description: '归档并交付 Classic change。在用户调用 /comet-archive,或 Classic Runtime 进入 Archive、恢复交付时使用。' --- # Comet 阶段 5:归档(Archive) 收到入口返回的 layout 后,按 `comet-classic/reference/classic-layout.md` 确定各逻辑根对应的目录。当前上下文已有这份协议时,无需重复加载。本文件中的 OpenSpec CLI 调用均通过适配器执行,文件路径均基于已绑定的 `` 根目录,无需先额外运行 root show。 ## 前置条件 - 验证已通过(阶段 4 完成) - 归档或所选交付动作尚未完成;恢复不要求 branch_status 仍为 pending - `/.comet.yaml` 中 `verify_result: pass` ## 步骤 ### 0. 设置输出语言 归档摘要和流程完成说明,使用本轮入口返回的 configuration.language,不再单独查询语言。 ### 0b. 入口状态验证(Entry Check) 按 `comet-classic/reference/scripts.md` 使用正式支持的 `comet` CLI,执行以下入口验证。从任意入口恢复任务时,先按 `comet-classic/reference/context-recovery.md` 检查恢复状态: ```bash comet state select comet state check archive --json ``` 上一阶段 guard 已成功返回本阶段状态信息时,直接使用其中的状态与 `agent.continuation` 继续,不重复 select/check;恢复任务、工作区变化或外部状态变化时,才执行上述入口验证。使用入口返回的 layout、configuration、nextAction 和 delivery 摘要继续。丢失上下文后恢复任务时,按 context-recovery.md 读取所需详情。已有授权仍然有效、交付目标也没有变化时,只继续未完成的动作,不重复询问。失败时,处理返回的具体原因。 若上述 `select` / `check` 输出 `BLOCKED` 或分支绑定 `ERROR`,且原因是 `bound_branch` 与当前分支不一致,立即按 `comet-classic/reference/decision-point.md` 暂停,让用户单选:切回绑定分支后重新运行入口验证,或在用户明确确认当前分支应接管该 change 后运行 `comet state rebind ` 并重新入口验证。不得自行切换分支,不得自行换绑。 ### 1. 请用户确认归档与交付方式 读取入口返回的 configuration.isolation 与 delivery。没有有效授权,或交付目标发生变化时,**按 decision-point.md 暂停,请用户确认归档和交付方式**。已有授权时,先由 Runtime 核对实际 Git 状态和交付进度,再按 nextAction 继续。不能仅凭 branch_status: handled 就认定用户已授权归档、push 或创建 PR,也不能在获得授权前运行 archive-confirm 或 archive。 确认前必须向用户展示简短摘要: - change 名称 - 验证报告路径和结论 - 当前分支、工作区,以及未提交改动分别属于哪些工作的核对结果 - 本次归档将执行的不可逆动作:按 OpenSpec delta 语义合并主 spec、标注 design doc / plan、移动 change 到 archive 目录 - 归档完成后将采用的提交处理方式:只保留在本地、推送当前绑定分支,或推送后创建 PR 用户确认问题必须以单选题形式呈现,包含以下全部选项。文本降级模式必须使用下表;使用结构化提问时,将“方式”作为短标签、“实际影响”作为说明,不得缩短为含义不明确的选项: | 选项 | 方式 | 实际影响 | | ---- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | A | 仅归档(不推送) | 完成归档并创建唯一归档提交;提交只保留在当前绑定分支,不推送、不创建 PR | | B | 「确认归档并立即推送」 | 完成归档并创建唯一归档提交,然后推送当前绑定分支;不创建 PR | | C | 「确认归档、立即推送并创建 PR」 | 完成归档并创建唯一归档提交,推送当前绑定分支,然后创建 PR | | D | 「需要调整或重新验证」 | 不归档;运行 `comet state transition archive-reopen` 回到 `phase: verify`,再调用 `/comet-verify`;若确认需要修复,再按验证失败决策回到 `/comet-build` | | E | 「暂不归档」 | 不运行 `archive-confirm` 或归档命令,不提交、不推送;保留未归档的 change、`phase: archive` 和 `branch_status: pending`,等待稍后再次调用 `/comet-archive` | 只有用户选择 A、B 或 C 后,才将选择保存为 JSON 并通过 Runtime 记录,再确认归档: ```bash comet state delivery --file comet state transition archive-confirm ``` JSON 包含 action(A=local、B=push、C=pr)、targetBranch,以及可选的 remote、commit 和 prUrl。初次记录时,只填写已确认的动作和目标;尚不知道的 commit/prUrl 不得伪造,等操作实际完成后再补写。 targetBranch 是接收归档提交的绑定分支,与 PR 的 base 分支含义不同。PR base 使用已有的明确配置;存在歧义时先澄清。存在多个 remote 时,明确推送目的地,不自行猜测。例如,用户已确认推送时: ```json { "action": "push", "targetBranch": "", "remote": "" } ``` 用文件工具保存 JSON,再传给 delivery --file。输入文件放在 change 目录之外(例如仓库根的 `delivery-input.json`),用后删除;不得写进 change 目录,尤其不得使用 `/.comet/delivery.json`——那是 Runtime 的交付记录,Runtime 会识别同一路径的大小写写法和文件系统别名,并直接报告输入路径冲突。输入只包含 action、targetBranch 和可选的 remote、commit、prUrl;schemaVersion 等字段属于 Runtime 记录,不得出现在输入中。归档提交确认后,在同一完整记录中追加 `"commit": ""`;action 为 pr 且 PR 已创建时,再追加真实 prUrl。commit 由 Runtime 保存在 Git 忽略的交付回执中,change 目录内被跟踪的 `delivery.json` 始终不含 commit;归档提交后 change 目录必须与该提交保持零差异,不得在其中新增、修改或删除文件,否则完整性校验失败。local 示例只需 action:local 和已确认 targetBranch,不要求 remote。 普通 `comet state delivery ` 只读取已保存的记录,入口摘要也不访问网络。恢复远端交付、上次调用没有返回明确结果,或准备宣告完成时,必须显式运行: ```bash comet state delivery --verify ``` 返回结果为 `{delivery, verification}`。delivery 是已保存的用户选择和执行进度,verification 是 Runtime 对实际 Git、远端分支和 PR 的只读核对结果。仅有 delivery 记录或入口检查成功,不能证明远端交付已经完成。按核对结果处理: - 已确认 not-yet-delivered,例如尚未首次 push,或已推送但尚未创建 PR:授权和目标仍然有效时,继续未完成的动作,再用 --verify 核对;不能仅因为 notVerified/needsVerification 就停止。 - unavailable,即网络、权限或服务故障导致无法确定实际结果,或出现目标冲突、结果不确定:保留记录并停止。先解决只读核对遇到的问题,不盲目重试 push,也不重复创建 PR。 delivery 写入或 transition 失败均停止。只有两者成功才继续 Step 2。用户选择 D 时运行 archive-reopen,旧交付授权应失效,重新验证后重新确认;选择 E 直接停止,不归档、提交、推送或设置 handled。 ### 2. 执行归档 运行归档脚本: ```bash comet archive "" ``` 脚本自动执行: 1. 入口状态验证(phase=archive, verify_result=pass, archive_confirmation=confirmed, archived=false) 2. 在归档前更新 Design Doc 的元数据(archived-with, status) 3. 在归档前更新 Plan 的元数据(archived-with) 4. 调用 OpenSpec archive 按 delta 语义合并主 spec 并移动 change 到归档目录 5. 检查主 spec 中没有残留仅用于增量规格的章节标题(delta-only section) 6. 在 OpenSpec 实际归档目录中更新 archived 状态,并处理 pending recovery 元数据,保证中断后能够恢复 如脚本返回非零退出码,报告错误并停止。 如脚本返回零退出码,归档完成。 脚本摘要中的 `X/Y steps succeeded` 以真实执行步骤计数,不会因 delta spec 同步或文档标注重复累计。 脚本会调用 OpenSpec 归档能力按 `ADDED/MODIFIED/REMOVED/RENAMED` 语义合并主 spec,并在归档后校验主 spec 中没有残留 delta-only section 标题。 如需预览而不实际执行,使用 `--dry-run` 参数。 ### 3. Spec 流程完成 Spec 从需求讨论到归档的完整流程如下,到此全部完成: ``` brainstorming → delta spec → 实施 → 验证 → 主 spec 合并 → design doc 标注 → 归档 ``` ### 4. 精确提交归档改动 归档脚本只移动文件和合并 spec,不会自动提交。归档完成后工作区会有以下未提交改动: - change 目录从 `/` 移动到 `/YYYY-MM-DD-/` - 主 spec 按 delta 语义合并的内容 - design doc / plan 的归档元数据标注 确认 delivery 中的实际授权仍有效,再写入兼容字段并运行最终 archive guard(前一条成功后才执行后一条): ```bash comet state set branch_status handled && comet guard archive ``` handled 只是兼容旧流程的状态字段,不能表示用户已授权 local/push/pr,也不能证明这些动作已成功。授权与执行结果以 delivery 记录和 Runtime 对实际 Git、远端的核对为准。状态写入或 guard 失败时停止。恢复任务时,先核对归档提交是否已经存在;存在就复用,不再创建第二个归档提交。 归档后读取 `git status --short`,与归档前按 dirty-worktree 协议记录的改动归属逐项核对。只允许暂存明确属于当前 change 的路径:change 原来所在的路径、脚本输出的实际 archive 路径、归档目录中已更新为 `branch_status: handled` 的 `.comet.yaml`、被本次 delta 更新的 main specs,以及当前 Design Doc/Plan 的归档元数据。无法确定某个路径的改动归属时,停止并请用户处理。 使用显式 pathspec 暂存核对后的路径,再检查 staged diff;不得使用全仓库暂存,也不得把用户已有改动混入归档提交: 提交说明沿用已生效的项目格式、语言和正文要求;已有明确规范时直接准备,无需额外询问。下方消息占位符必须替换为实际说明,不能把示例英文模板当作项目规范。项目 Git Hooks 正常执行;被拒绝时保留暂存内容,修正说明后继续同一次提交。提交调用中断或结果不确定时,先核对实际 Git 记录,不盲目重提,也不绕过 Hook。 ```bash git add -- <逐项核对后的归档路径...> git diff --cached --stat git commit -m "<符合项目规范的归档说明>" ``` 提交失败或 staged diff 含无关路径时停止,不得继续分支处理。 ### 5. 交付归档提交并完成 归档提交成功后,用 `state delivery --file` 补写实际 commit,再由 Runtime 核对归档提交与交付目标。根据核对结果,只执行已授权且未完成的动作。记录失败时停止交付,不重新提交;恢复时,先核对已有 Git 提交和分支状态,再补齐记录。交付回执由 Runtime 保存,不能为了记录 commit 而反复创建归档提交。 - A「仅归档(不推送)」:不执行任何远端操作,归档提交只保留在当前绑定分支。 - B「确认归档并立即推送」:推送当前绑定分支一次。 - C「确认归档、立即推送并创建 PR」:先推送当前绑定分支一次,再通过已配置的 GitHub 集成创建 PR;Step 1 的明确选择就是创建 PR 的授权,不得再次改成其他分支处置方式。 push 或 PR 调用后,使用 delivery --verify 核对实际远端分支和 PR。PR 创建成功后,通过 delivery --file 补写实际 prUrl,并保留此前的 action、目标和 commit。调用超时或没有返回明确结果时,先查询实际结果,不能盲目重试。失败时保留 delivery 和 current selection,只继续已授权但尚未完成的动作;不得改写、删除或切换分支。 local 由 Runtime 确认归档提交存在;push 还需确认远端包含该提交;pr 还需确认对应 PR 存在且目标匹配。仅填写 commit/prUrl 不等于交付成功。所选动作全部经 Runtime 核对完成后,才运行 clear-selection 并宣告完成。 归档阶段不再调用 Superpowers `finishing-a-development-branch`,也不提供本地合并、切换、删除或变基等分支拓扑操作。用户只想完成本地归档时,必须在 Step 1 选择 A;用户尚不想归档时,选择 E。 ## 退出条件 - 归档脚本执行成功(退出码 0) - 归档目录 `/YYYY-MM-DD-/` 存在 - 归档后的 `.comet.yaml` 中 `archived: true` - 归档状态中的 `branch_status: handled` 已包含在唯一归档提交中 - `comet guard archive` 通过 - 唯一归档提交已按用户在归档前确认的方式处理:选择 A 时只保留本地,选择 B 时已成功推送,选择 C 时已成功推送并创建 PR - current selection 已在所选处理方式完成后清除 归档脚本会把 `/` 移动到 `/YYYY-MM-DD-/`。 `comet guard archive` 会按原 change 名解析实际归档目录;不要手工拼接日期目录名。 ## 完成 Comet Classic 流程全部完成。如需开始新的 Classic 工作,调用 `/comet-classic` 或 `/comet-open`。 ## 上下文压缩恢复 按 context-recovery.md 执行,phase 为 archive。读取已保存的 delivery 记录,不能依赖当前对话回忆用户选过 A、B 还是 C。Runtime 核对归档目录、提交、远端和 PR 后,只继续尚未完成的动作;local 不执行远端操作。旧 change 只有 handled 记录、缺少授权、交付目标发生变化,或分支关系与记录不一致时,停止并请用户明确确认。不能自行推断授权,也不能自动调整分支关系。