深入解析 `gsd-sdk query validate.health`:get-shit-done 规划目录完整性体检如何消除三类误报

深入解析 `gsd-sdk query validate.health`:get-shit-done 规划目录完整性体检如何消除三类误报 深入解析gsd-sdk query validate.healthget-shit-done 规划目录完整性体检如何消除三类误报【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done本文围绕 get-shit-doneGSDSDK 查询处理器validate.health的最新修复展开它针对真实工作流中高发的三类“健康体检误报”——999.X待办清单backlog阶段目录、里程碑归档milestone-archive布局下的阶段目录以及带描述符的 PLAN/SUMMARY 文件名配对——逐一修正判定逻辑。读完本文你将理解 GSD 规划体系.planning/的目录布局约束、validate.health的十余项检查清单与输出契约并能直接通过gsd-sdk query validate.health对项目做准确、无噪声的完整性诊断。该修复记录于 changeset 片段 .changeset/graceful-geese-tumble.mdPR 3479类型Fixed其对应的全部实现与回归测试均可在此仓库内直接核对。一、背景为什么需要一个“会体检”的查询处理器get-shit-done 是一个面向 Claude Code 的元提示meta-prompting与上下文工程系统它以“规格驱动开发”为核心每个项目在.planning/目录下维护一套高度结构化的规划产物包括PROJECT.md、ROADMAP.md、STATE.md、config.json以及phases/活动阶段目录、milestones/归档阶段目录等。由于这套规划文件既是 Agent 决定“下一步做什么”的依据也是各 slash 命令/gsd-plan-phase、/gsd-execute-phase等的输入规划目录一旦出现缺文件、错命名、编号断档就会向下游放大为执行错误。因此仓库提供了验证类查询处理器validate 家族做“体检”其中validate.consistency——跨文件一致性扫描编号断档、PLAN/SUMMARY 配对、frontmatter 完整性等validate.health——最综合的 10 项完整性检查支持--repair自动修复是本文主角validate.agents、validate.context——分别校验 Agent 文件安装与上下文窗口利用率。它们被统一注册在validate.*命令清单中见 sdk/src/query/command-manifest.validate.ts并由 sdk/src/query/command-family-handlers.ts 映射到实际执行函数。validate.health的实现位于 sdk/src/query/validate.tsTypeScript 原生实现由旧版verify.cjs移植而来其注册名canonical: validate.health、别名validate healthmutation: false、outputMode: json即它是一个只读的 JSON 查询命令。调用方式SDK 查询、CLI 与 slash 命令validate.health有三种等价入口均输出结构化 JSON# 1. SDK 查询推荐注册表中的规范化点号名或空格别名皆可 gsd-sdk query validate.health gsd-sdk query validate health # 2. 旧版 CJS 入口gsd-tools.cjs node gsd-tools.cjs validate health # 3. Claude Code 内的 slash 命令 /gsd-health # 仅体检 /gsd-health --repair # 体检并自动修复可恢复问题其中--repair是validateHealth处理器的核心参数args.includes(--repair)用于自动修复可恢复缺陷见下文的修复清单。若在本仓库源码目录内直接调用 SDK可先构建 SDK 后执行node ./sdk/dist/cli.js query validate.healthSDK 用法详见 sdk/README.md。二、validate.health的检查清单与输出契约2.1 输入前置.planning/与 CWD 守卫处理器首先执行“家目录守卫”E010若解析后的projectDir等于用户主目录说明当前工作目录错误此时体检会读到错误的.planning/处理器直接返回status: error并给出修复建议cd into your project directory and retry见 sdk/src/query/validate.ts。随后建立两类路径基线planBase .planning/roadmapPath .planning/ROADMAP.md。2.2 逐项检查Check 1–10处理器按固定顺序执行以下检查源码中的代码即各 Check 的注释锚点全部位于 sdk/src/query/validate.ts检查判定项输出 issueCheck 1.planning/目录是否存在缺失报E001Check 2PROJECT.md是否存在是否含## What This Is/## Core Value/## Requirements三个必需小节缺失报E002缺小节报W001Check 3ROADMAP.md是否存在缺失报E003Check 4STATE.md是否存在及其引用的阶段是否合法缺失报E004可修复引用未声明阶段报W002Check 5 / 5bconfig.json是否为合法 JSON、schema 校验、workflow.nyquist_validation键是否存在解析错误报E005可修复model_profile非法报W004缺文件报W003缺键报W008Check 6阶段目录命名是否符合NN-name格式不符报W005Check 7孤立 PLAN有 PLAN 无 SUMMARY报I001仅信息Check 7bRESEARCH 中含## Validation Architecture但缺 VALIDATION.md报W009Check 8ROADMAP 与磁盘阶段目录双向同步ROADMAP 有、磁盘无报W006磁盘有、ROADMAP 无报W007Check 9STATE.md 当前阶段与 ROADMAP 完成状态交叉校验状态不同步报W011Check 10config.json字段取值合法性branching_strategy、context_window、分支模板占位符分别报W012–W015其中 Check 4、Check 8 正是本文修复的三类误报中“里程碑归档目录”与“999.X 目录”所涉及的核心逻辑所在。2.3 输出契约与状态推导处理器把所有 issue 收集为errors / warnings / info三个数组并按以下规则推导整体statussdk/src/query/validate.ts存在任何error→broken无 error 但有warning→degraded全部干净 →healthy。输出 data 中还包含repairable_count可修复错误 可修复警告之和以及repairs_performed执行过--repair时列出实际修复动作。同时每个 issue 项带code、message、fix字段便于 Agent 直接消费后给出处理建议。2.4--repair的三种自动修复动作当传入--repair且检测到可修复问题时处理器会执行createConfig/resetConfig写入一组“只含安全默认值”的config.json默认model_profile: balanced、branching_strategy: none、workflow.nyquist_validation: true等见 sdk/src/query/validate.tsregenerateState根据 ROADMAP 结构重新生成最小化STATE.mdsdk/src/query/validate.tsaddNyquistKey为已有config.json的workflow补写nyquist_validation: truesdk/src/query/validate.ts。值得注意的是修复程序只写“已知安全”的默认值绝不臆造项目语义因此设计上避免把体检工具变成数据破坏者。三、三类误报的本质与修复原理Changeset 片段明确指出本次修复让validate.health规避了三类误报false-positive接受999.X待办清单阶段目录在做“ROADMAP 是否存在”类检查时识别里程碑归档阶段目录规范化带描述符的 PLAN/SUMMARY 文件名配对。下面结合源码逐一展开。3.1 第一类接受999.Xbacklog 阶段目录消除错误 W005为什么会产生误报。get-shit-done 的“待办清单停车区”Backlog Parking Lot设计规定backlog 项使用999.x编号使其天然落在活动阶段序列01、02…之外需求文档见 docs/FEATURES.md。当一个 backlog 项被捕获时会立刻创建对应的阶段目录例如.planning/phases/999.1-backlog-sweep/目录布局在 docs/FEATURES.md命令用法见 docs/COMMANDS.md。在早期版本的 Check 6 阶段目录命名检查中目录名若不以“两位数字 - 描述”的形态出现就会触发W005“doesnt follow NN-name format”。但999.1-backlog-sweep这类目录由/gsd-capture --backlog合法产生命名单本身满足仓库约定却被误判为“格式异常”导致健康项目始终处于degraded状态。修复方式。Check 6 的命名正则被放宽为兼容多位整数 可选小数段的形态// Check 6 阶段目录命名校验W005现接受 999.X backlog 目录 if (e.isDirectory() !e.name.match(/^\d{2,}(?:\.\d)*-[\w-]$/)) { addIssue(warning, W005, Phase directory ${e.name} doesnt follow NN-name format, ...); }即段首要求“两位及以上数字”随后允许(?:\.\d)*的任意小数扩展.1、.2…再跟-[\w-]。999.1-backlog-sweep完全匹配而真正不规范的bad_name依旧会被正确拦截。回归测试锚点。sdk/src/query/validate.test.ts 的用例does not emit W005 for 999.X backlog phase directory naming (#3473)创建了.planning/phases/999.1-backlog-sweep后断言不出现指向该目录的W005同文件上方还保留了对bad_name触发W005的对照组用例确保修复没有把命名检查“一刀切放掉”。3.2 第二类ROADMAP 存在性检查识别里程碑归档目录消除错误 W006/W007背景里程碑归档布局。当一个里程碑vX.Y完成时milestone.complete或 SDK 专属的phases.archive会把活动阶段目录整体搬移到归档布局.planning/milestones/milestone-phases/下归档行为可见 tests/milestone-archive.test.cjsv1.0-phases目录即归档产物。也就是说历史里程碑的阶段例如.planning/milestones/v1.7-phases/64-secondary-grader-fix/不再位于扁平的.planning/phases/下。为什么会产生误报。Check 8 做“ROADMAP ↔ 磁盘阶段目录”双向同步检查时若只扫描扁平的.planning/phases/那么 ROADMAP 中已发货SHIPPED里程碑声明的阶段会找不到对应磁盘目录从而误报W006“Phase in ROADMAP.md but no directory on disk”。反向同理只有归档目录、没有扁平目录的阶段可能误报W007。修复方式源码级三层配合枚举归档目录listMilestoneArchiveDirs扫描.planning/milestones/下所有匹配/^v\d.*-phases$/i的目录并按版本号数值排序v1.10排在v1.2之后见 sdk/src/query/validate.ts。收集归档阶段 tokenforEachArchivedPhaseToken遍历每个归档目录下的阶段子目录用PHASE_TOKEN_FROM_DIR_RE兼容CK-64-...这类项目代码前缀命名提取规范阶段号并回调见 sdk/src/query/validate.ts。并入“磁盘有效阶段”集合Check 8 在统计diskPhases后把归档 token 一并并入await forEachArchivedPhaseToken(planBase, (token) diskPhases.add(token))于是 ROADMAP 声明的历史阶段被认为“存在”不再触发W006而W007仍只针对扁平活动目录中的“真孤儿”不会把归档目录里的历史阶段当作当前多余阶段见 sdk/src/query/validate.ts。同样的归档识别思路也用于 Check 4W002STATE.md 阶段引用合法性forEachArchivedPhaseToken把归档阶段的 token 视为合法引用避免跨里程碑引用历史阶段被误报sdk/src/query/validate.ts。回归测试锚点。单元测试层sdk/src/query/validate.test.ts 构造 ROADMAP 中“Phase 7”仅存在于.planning/milestones/v1.0-phases/07-old-shipped-phase/的场景断言不出现指向 Phase 7 的W006sdk/src/query/validate.test.ts 反向验证纯归档阶段目录不触发W007。集成测试层tests/milestone-archive.test.cjs 直接通过gsd-tools validate health在归档布局项目上断言Phase 64无“no directory”类W006。这些测试覆盖了#3164validate 家族识别归档布局与#3473两个历史 issue 的回归诉求。3.3 第三类规范化 PLAN/SUMMARY 文件名配对消除错误 I001为什么会产生误报。GSD 的规划产物允许阶段文件带“描述符”descriptor。例如某阶段目录同时存在68-01-scaffolding-PLAN.md带描述符scaffolding的计划文件68-01-SUMMARY.md不带描述符的总结文件两者本质属于同一对68-01。但 Check 7 的“孤儿计划”检查在早期版本按字面文件名比对会认为68-01-scaffolding-PLAN.md没有对应的68-01-scaffolding-SUMMARY.md从而产生信息级误报I001“has no SUMMARY.md, may be in progress”。虽然只是info但噪声化的info会污染状态推导与 Agent 决策。修复方式。引入规范化配对函数canonicalPlanStem把文件名主干中“阶段号-计划号”之后的描述符剥离得到规范主干/** * Canonical plan stem used for PLAN/SUMMARY matching. * Example: 68-01-scaffolding - 68-01. */ function canonicalPlanStem(stem: string): string { const m stem.match(/^(\d[A-Z]?(?:\.\d)*-\d)/i); return m ? m[1] : stem; }Check 7 先为每个 SUMMARY 记录其主干与规范主干再判断每个 PLAN 是否存在与自身字面主干或规范主干匹配的 SUMMARYsummaryBases.add(summaryBase); // e.g. 68-01 summaryBases.add(canonicalPlanStem(summaryBase)); // 归一化后仍为 68-01 // 对每个 plan只要 PLAN 主干或其规范化主干命中 SUMMARY 集合即视为成对 const canonicalBase canonicalPlanStem(planBase2); if (!summaryBases.has(planBase2) !summaryBases.has(canonicalBase)) { addIssue(info, I001, ${e.name}/${plan} has no SUMMARY.md, May be in progress); }这样68-01-scaffolding-PLAN.md规范主干68-01能与68-01-SUMMARY.md正确配对I001不再误报。这一规范化逻辑同时服务于 validate 家族另一处理器的一致性检查sdk/src/query/validate.ts 定义了该函数Check 7 使用之。回归测试锚点。sdk/src/query/validate.test.ts 构造.planning/phases/68-bug-surface/下仅含68-01-scaffolding-PLAN.md与68-01-SUMMARY.md的场景断言不产生指向该 PLAN 文件的I001。四、从实现看设计validate 家族为何值得信赖把上述三处修复放在一起看能提炼出 get-shit-done 验证体系的几个设计原则这些都直接体现在代码与测试中“目录布局变体”是被显式建模的一等公民。归档布局、backlog 的999.X编号、项目代码前缀如CK-64-...都不是异常而是合法状态。验证器通过listMilestoneArchiveDirs、forEachArchivedPhaseToken、collectPhaseRoots等辅助函数把布局变体显式纳入集合计算而不是靠“忽略警告”来掩盖问题。阶段号比较一律“规范化”后做。无论是 STATE.md 引用Check 4、ROADMAP 同步Check 8还是文件名配对Check 7比较时都会把64/64A/06.1/0064等变体归一到规范 token 或补零变体再比较phaseVariants与补零逻辑可见 sdk/src/query/validate.ts 与 sdk/src/query/validate.ts既消除格式误报也保证22A不会被误折叠成22有专门测试守护does not alias 22A to 22 when suppressing W006。issue 带 code fix 建议Agent 可直接执行。每条 issue 都携带稳定的错误码E001–E015、W001–W015、I001、I010等与修复指引字符串配合repairable_count/--repair形成了“体检 → 归因 → 自动修复 → 再验证”的闭环。4.1 相关文档与进一步阅读查询处理器注册契约与路由总表sdk/src/query/QUERY-HANDLERS.mdvalidate 家族位列“Registered”。validate 命令清单定义sdk/src/query/command-manifest.validate.ts。validate 家族处理器映射sdk/src/query/command-family-handlers.ts。slash 命令用户文档--repair/--context参数docs/COMMANDS.md。backlog 捕获与 999.x 编号约定docs/COMMANDS.md 与 commands/gsd/capture.md。归档布局集成测试#2684/#3164/#3600tests/milestone-archive.test.cjs。五、实战如何验证你的项目已“健康”以源码仓库或任意 GSD 项目为例确认修复生效与整体体检无噪声# 在项目根目录执行体检必须包含 .planning/ gsd-sdk query validate.health # 期望输出中 status 为 healthy / degraded并给出结构化 issue 列表 # 若 ROADMAP 存在已发货里程碑而其阶段已归档到 .planning/milestones/vX.Y-phases/ # 则不应再出现指向这些历史阶段的 W006对三类误报场景做针对性自检场景构造修复前修复后存在.planning/phases/999.1-backlog-sweep/错误W005无W005ROADMAP 声明 Phase 7磁盘上仅有.planning/milestones/v1.0-phases/07-old-shipped-phase/错误W006无W006同目录下仅68-01-scaffolding-PLAN.md68-01-SUMMARY.md错误I001无I001如需自动修复可恢复缺陷重建缺失的config.json/STATE.md、补nyquist_validation键在确认这些文件确属丢失后执行gsd-sdk query validate.health --repair若想对运行环境做上下文窗口利用率体检可使用/gsd-health --context阈值规则小于 60% 为healthy60%–70% 为warning达到 70% 及以上为critical见 sdk/src/query/validate.ts。需要提醒的适用前提validate.health的判定模型面向 GSD 自身生成的.planning/结构检查是否命中.planning目录、ROADMAP 阶段编号与目录命名约定等均以本仓库 sdk/src/query/validate.ts 中实现为准若项目启用了phase_naming: custom或其它非默认规划布局检查口径会相应走自定义分支例如编号断档检查会整体跳过见 sdk/src/query/validate.ts。结语validate.health的三类误报修复是 get-shit-done “用工程化手段治理 AI 工作流”思路的缩影验证器必须深刻理解自身的目录布局语义把“归档”“backlog”“描述符命名”这些真实状态都当作合法输入才能真正成为值得 Agent 信赖的体检仪。从 changeset 一行描述出发本次修复在 sdk/src/query/validate.ts 中落实为命名正则放宽、归档 token 并入磁盘阶段集合、以及 PLAN/SUMMARY 规范化配对三处逻辑变更并由 sdk/src/query/validate.test.ts 与 tests/milestone-archive.test.cjs 中的多组回归用例钉死确保此后任何改动都不会让这三类误报“复活”。【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考