get-shit-done 阶段目录归档工作流:用 /gsd:cleanup 整理已完成里程碑的 .planning/phases
导读
在 get-shit-done(GSD)的 spec-driven 开发流程中,每个里程碑(Milestone)由若干阶段(Phase)目录组成,长期迭代后 .planning/phases/ 会堆积大量历史阶段目录,拖累上下文加载与目录检索。cleanup 工作流专门解决这一问题:它读取 .planning/MILESTONES.md 识别已完成里程碑,依据归档的 ROADMAP 快照判定各阶段归属,以 dry-run 摘要向用户确认后,把阶段目录移入 .planning/milestones/v{X.Y}-phases/ 并提交变更。读完本文,你将掌握 cleanup 工作流的完整执行协议、安全确认机制、底层源码实现,以及如何在非 Claude 运行时(Codex、Gemini CLI 等)下以文本模式驱动它。
一、工作流定位:为什么需要阶段归档
1.1 目录结构中的角色
get-shit-done 的规划工作区以 .planning/ 为根,其典型布局如下(参见 工作流帮助文档):
.planning/
├── MILESTONES.md # 里程碑总表与状态
├── ROADMAP.md # 当前阶段分解
├── STATE.md # 项目记忆与上下文
├── config.json # 工作流模式与门禁
├── milestones/
│ ├── v1.0-ROADMAP.md # 归档的路线图快照
│ ├── v1.0-REQUIREMENTS.md # 归档的需求快照
│ └── v1.0-phases/ # 归档的阶段目录(由 /gsd:cleanup 或 --archive-phases 产生)
│ ├── 01-foundation/
│ └── 02-core-features/
└── phases/
├── 01-foundation/
│ ├── 01-01-PLAN.md
│ └── 01-01-SUMMARY.md
└── 02-core-features/
├── 02-01-PLAN.md
└── 02-01-SUMMARY.md
cleanup 工作流正是把 .planning/phases/ 中已完成里程碑的阶段目录搬运到 .planning/milestones/v{X.Y}-phases/ 的专职流程,与 complete-milestone 工作流中的可选归档步骤(Archive Phases 确认框)形成互补:前者随里程碑完成即时归档,后者用于事后集中清理。
1.2 归档后的可检索性保障
归档并不等于"丢弃"。仓库测试明确验证了归档阶段的可发现性:milestone-archive 测试 证明 find-phase 查询会按确定性排序搜索 .planning/milestones/v*-phases/ 目录——例如在 v1.10-phases/ 与 v1.2-phases/ 同时存在 64 号阶段时,结果稳定返回 v1.2-phases/64-from-12;未命中时返回的 searched_directories 数组会列出全部被检索的归档目录。此外 verify-health 测试 要求归档目录与 ROADMAP.md 中的 #### Phase N: 标题保持一致。这意味着 cleanup 执行完毕后,历史阶段仍可通过查询工具与健康检查被追溯,不会造成"清理即丢失"。
二、cleanup 工作流完整执行协议
cleanup 工作流(workflows/cleanup.md)由 6 个顺序步骤组成:识别已完成里程碑 → 判定阶段归属 → 展示 dry-run 摘要并确认 → 移动阶段目录 → 提交 → 汇报。下面逐步骤给出可复制的命令与决策逻辑。
2.1 步骤 1:识别已完成里程碑(identify_completed_milestones)
首先读取里程碑总表:
cat .planning/MILESTONES.md
从中提取每个已完成里程碑的版本号(例如 v1.0、v1.1、v2.0)。随后检查哪些版本已有归档目录:
ls -d .planning/milestones/v*-phases 2>/dev/null || true
过滤出尚未拥有 -phases 归档目录的里程碑。若全部里程碑都已归档,直接输出:
All completed milestones already have phase directories archived. Nothing to clean up.
并终止流程。这一"先查存量、再定清理集"的策略保证 cleanup 是幂等的:重复执行不会产生重复归档。
2.2 步骤 2:判定阶段归属(determine_phase_membership)
对每个无归档的已完成里程碑,读取其归档的 ROADMAP 快照以确定阶段清单:
cat .planning/milestones/v{X.Y}-ROADMAP.md
从快照中提取阶段编号与名称(如 Phase 1: Foundation、Phase 2: Auth)。然后列出当前实际存在的阶段目录:
ls -d .planning/phases/*/ 2>/dev/null || true
关键约束:只有"仍然存在于 .planning/phases/ 中"的目录才会被纳入归档集合——若某阶段目录已被手动删除或此前已归档,则不参与本次移动。这一步把 ROADMAP 快照(声明的归属)与磁盘实况(实际的存在性)对齐,避免移动不存在的路径。
2.3 步骤 3:展示 dry-run 摘要并请求确认(show_dry_run)
在动手前必须先向用户呈现拟归档清单:
## Cleanup Summary
### v{X.Y} — {Milestone Name}
These phase directories will be archived:
- 01-foundation/
- 02-auth/
- 03-core-features/
Destination: .planning/milestones/v{X.Y}-phases/
### v{X.Z} — {Milestone Name}
These phase directories will be archived:
- 04-security/
- 05-hardening/
Destination: .planning/milestones/v{X.Z}-phases/
若没有任何待归档阶段目录(全部已移动或已删除):
No phase directories found to archive. Phases may have been removed or archived previously.
此时同样终止流程。否则通过 AskUserQuestion 提供两个选项:
Yes — archive listed phasesCancel
选择 Cancel 则立即停止。
文本模式(Text mode):当配置项 workflow.text_mode: true 或命令行带 --text 标志时,TEXT_MODE 被置为 true,此时必须把每次 AskUserQuestion 调用替换为纯文本编号列表,让用户直接输入选项数字。该机制专门服务于非 Claude 运行时(OpenAI Codex、Gemini CLI 等不支持 AskUserQuestion 的环境),保证工作流在跨 AI 运行时保持可用。
2.4 步骤 4:移动阶段目录(archive_phases)
对每个里程碑逐一执行归档:
mkdir -p .planning/milestones/v{X.Y}-phases
然后移动该里程碑下每个阶段目录:
mv .planning/phases/{dir} .planning/milestones/v{X.Y}-phases/
对清理集中的全部里程碑重复上述操作。由于移动发生在 .planning/ 内部,阶段目录内的 PLAN.md、SUMMARY.md 等工件随目录整体搬迁,无需逐个文件处理。
2.5 步骤 5:提交变更(commit)
使用 SDK 查询层提交,显式指定涉及的两个根路径:
gsd-sdk query commit "chore: archive phase directories from completed milestones" --files .planning/milestones/ .planning/phases/
提交实现 会为每个 --files 路径执行 git add -- <path>,并确保最终提交只包含 --files 指定范围内的已暂存文件;若 --files 为空,提交处理器将无法推断阶段归属而直接返回 --files requires at least one path 的失败结果(见 commit.ts),因此归档提交必须显式传参。
2.6 步骤 6:汇报结果(report)
Archived:
{For each milestone}
- v{X.Y}: {N} phase directories → .planning/milestones/v{X.Y}-phases/
.planning/phases/ cleaned up.
三、成功标准与错误分支汇总
cleanup 工作流在 workflows/cleanup.md 中定义了明确的成功标准:
- [ ] 所有无既有阶段归档的已完成里程碑均被识别
- [ ] 阶段归属依据归档的 ROADMAP 快照判定
- [ ] dry-run 摘要已展示且获得用户确认
- [ ] 阶段目录已移入
.planning/milestones/v{X.Y}-phases/ - [ ] 变更已提交
同时存在四个终止分支(均为正常结束而非报错):
| 场景 | 输出/行为 |
|---|---|
| 全部里程碑已有归档 | All completed milestones already have phase directories archived. 并停止 |
| 无待归档阶段目录 | No phase directories found to archive. 并停止 |
| 用户选择 Cancel | 停止,不做任何移动 |
| 文本模式确认 | 以编号列表替代 AskUserQuestion,等待用户输入选项数字 |
四、底层支撑:规划路径与查询工具链
4.1 规划路径的单一来源
阶段与里程碑目录路径由 SDK 的 planningPaths(projectDir, workstream) 统一提供(见 phase-lifecycle.ts),工作流中的 phases 与 milestones 路径均来自该函数,保证命令行手写路径与 SDK 内部路径一致,避免路径漂移。
4.2 归档目录参与阶段查询
归档后阶段仍可被 find-phase 检索。测试覆盖表明,即使删除了 .planning/phases/,find-phase 依然能按字典序搜索所有 v*-phases 归档目录并返回 found: true 与完整目标目录(见 milestone-archive.test.cjs)。这从源码层面印证了 cleanup 是"归档"而非"清理销毁",历史工件始终可回溯。
4.3 与其他工作流的衔接
- complete-milestone:其结尾包含可选的
Archive Phases确认(Yes — move to milestones/v[X.Y]-phases/或Skip),负责即时归档;cleanup 则承担事后批量清理。 - 状态切换安全:归档移动发生在
.planning/phases/与.planning/milestones/之间,不触碰STATE.md等状态文件,因此不会破坏当前里程碑的上下文权威(参见仓库对状态写入路由的既有约束)。
五、实战建议与运行前提
- 先跑只读命令,再执行移动:
cat与ls -d均为只读探测,可放心重复执行;只有mv与commit会产生变更,且必须建立在用户确认之上。 - 归档不丢历史:由于
find-phase会检索v*-phases/归档目录(确定性排序、含searched_directories反馈),建议为归档阶段保留清晰命名(如NN-name),便于后续按编号精准回溯。 - 文本模式适用于跨运行时:在 Codex、Gemini CLI 等环境中,确保配置
workflow.text_mode: true或传入--text,让确认环节退化为纯文本编号列表,避免因AskUserQuestion不可用而卡死。 - 提交必须显式传
--files:SDK 提交层在--files缺失时不会猜测范围(--files requires at least one path),请始终按第 2.5 节方式同时传入.planning/milestones/与.planning/phases/。 - 健康检查兜底:归档目录需与
ROADMAP.md的阶段标题保持一致(verify-health 测试),若后续手工调整了归档目录命名,建议运行健康验证确认无 W006 类告警(见 milestone-archive.test.cjs)。
小结
cleanup 工作流是 get-shit-done 规划工作区长期可维护性的关键一环:它以"ROADMAP 快照定归属、磁盘实况定范围、dry-run 定确认、显式 --files 定提交"四重约束,把阶段归档做成幂等、可审计、跨运行时兼容的规范操作。结合 find-phase 对归档目录的确定性检索与健康检查的一致性校验,团队可以在保持工作区整洁的同时,完整保留每个里程碑的阶段级历史证据。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.22 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python400
cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端TypeScript2 K146
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python48467
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go20843
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java34451