首页
/ get-shit-done Changeset 实战:解析 sunny-ibex-wave 片段与 gsd-intel-updater 布局检测门控修复(3290)

get-shit-done Changeset 实战:解析 sunny-ibex-wave 片段与 gsd-intel-updater 布局检测门控修复(3290)

2026-09-07 16:27:02作者:裘旻烁

在 get-shit-done(GSD)仓库中,.changeset/ 目录下的每个 Markdown 片段都是"每 PR 一条 CHANGELOG"机制的最小单元,用于避免多个 PR 同时编辑 CHANGELOG.md 产生合并冲突。本文以真实存在的片段 .changeset/sunny-ibex-wave.md 为主体,拆解它的 frontmatter 格式与成文规范,并顺着它记录的修复内容深入源码:gsd-intel-updater 智能体中那段"运行时布局检测"bash 块,是如何被门控在"当前项目就是 GSD 框架自身仓库"这一前置条件之下的。读完本文,你将能读懂并校验一个 changeset 片段,并理解这类"死代码但吵闹"(dead-but-noisy)提示行的定位、修复与回归测试设计方法。

一、Changeset 片段的完整格式与生成方式

先给出被分析对象的全文(.changeset/sunny-ibex-wave.md):

---
type: Removed
pr: 3299
---
**`gsd-intel-updater` no longer emits a vestigial "Layout detection returned 'unknown'" line on non-GSD-framework projects** — the layout-detection bash block is now gated on a positive framework-repo check (package.json name = "get-shit-done-cc"), so ordinary user projects skip the step silently.

它由两部分构成:

组成 取值 说明
type Removed 允许值遵循 Keep a Changelog 约定:AddedChangedDeprecatedRemovedFixedSecurity(见 .changeset/README.md
pr 3299 关联 PR 编号,用于溯源
正文 一句话 以加粗命令/符号名开头,说明用户可见的行为变化

之所以采用"每 PR 一个独立文件"而非直接改 CHANGELOG.md.changeset/README.md 给出的理由是:两个 PR 同时编辑 ### Fixed 区块必然冲突,而各自新增一个唯一命名的 .changeset/<unique-name>.md 则互不共享行、永不冲突。片段文件名的 <形容词>-<名词>-<名词>.md(如 sunny-ibex-wave)也是随机生成,进一步降低并发冲突概率。

标准生成方式(来自 .changeset/README.md):

node scripts/changeset/new.cjs \
  --type Fixed \
  --pr 1234 \
  --body "fix the thing — explain the user-visible change in one sentence"

对无用户可见影响的 PR,可用 no-changelog 标签豁免;拿不准时宁可加片段。

二、缺陷背景:gsd-intel-updater 在普通项目里的"幽灵输出"

片段正文里的 gsd-intel-updater 是 GSD 的代码库情报智能体,其指令定义在 agents/gsd-intel-updater.md。它的职责是读取项目源码、把结构化的"情报"写入 .planning/intel/stack.jsonfiles.jsonapis.jsondeps.jsonarch.md 五个文件),供其他智能体以可查询的知识库代替昂贵的全库探索读取。该智能体由 /gsd:map-codebase --query 命令派生,且上游已确认 intel.enabledtrue 才会启动。

修复前的问题(回归测试文件头部注释给出了完整定性):gsd-intel-updater.md 中的 "Runtime layout detection" 块在每一个被分析的项目上无条件执行,对所有普通(非 GSD 框架)用户项目都会输出一行:

Layout detection returned "unknown" — this project is not a GSD-system installation (no .claude/get-shit-done/ or .kilo/ runtime root).

关键在于:这个"判定结果"在后续 Step 2–6 中对非 GSD 项目本来就会被忽略,所以这段输出是"死代码但吵闹"(dead-but-noisy)——无功能价值,只污染输出。这一点由回归测试 tests/bug-3290-intel-updater-layout-block.test.cjs 的文件头注释明确记录(第 10–17 行)。

三、修复方案:正向"框架仓库"门控

修复的核心是:把布局检测 bash 块门控在正向框架仓库检查之下——仅当 package.json"name" 等于 "get-shit-done-cc"(即当前项目就是 GSD 框架自身仓库,这一点可以由本仓库根目录 package.json"name": "get-shit-done-cc" 印证)时才运行检测。修复后的指令块位于 agents/gsd-intel-updater.md

# Only run layout detection when analysing the GSD framework repo itself.
if [[ "$(jq -r '.name // ""' package.json 2>/dev/null)" == "get-shit-done-cc" ]]; then
  ls -d .kilo 2>/dev/null && echo "kilo" || (ls -d .claude/get-shit-done 2>/dev/null && echo "claude") || echo "unknown"
fi

指令文本同时给出行为契约(同文件第 60、71 行):

  • 检测块上方注释:<!-- Layout detection: only meaningful when analysing the GSD framework's own repo (#3290). -->
  • 块下方说明:For all other projects, skip this step and proceed directly to Step 1.

即普通用户项目会静默跳过该步骤,直接进入 Step 1(目录定位),不再产生任何 "Layout detection returned 'unknown'" 行。

布局检测在做什么:两套运行布局的规范路径

门控之内的那段检测,输出三种判定:kiloclaudeunknown,用于选择"规范源位置"。agents/gsd-intel-updater.md 给出的路径对照表是:

资源类型 标准 .claude 布局 .kilo 布局
智能体文件 agents/*.md .kilo/agents/*.md
命令文件 commands/gsd/*.md .kilo/command/*.md
CLI 工具 get-shit-done/bin/ .kilo/get-shit-done/bin/
工作流文件 get-shit-done/workflows/ .kilo/get-shit-done/workflows/
参考文档 get-shit-done/references/ .kilo/get-shit-done/references/
Hook 文件 hooks/*.js .kilo/hooks/*.js

配套规则(同文件第 84–93 行):一旦检测到 .kilo 根,就只用 .kilo 下的规范位置,不回落标准布局——因为空路径会产生"语义空"的情报文件;组件计数必须通过对布局解析后的规范位置执行 Glob 得出,而不是凭记忆。

为什么选择"门控"而非"删除"

回归测试注释中列出了两个候选方案:方案 A 是用框架仓库守卫包住检测块;方案 B 是彻底删除。测试断言的逻辑(tests/bug-3290-intel-updater-layout-block.test.cjs)也对应这两条路径:若裸检测块已被整体删除则直接通过;若块仍存在,则验证它被框架仓库门控(检查内容中出现 get-shit-done-cc 或等价守卫语义)。当前仓库选择了方案 A,因为布局检测对"分析 GSD 框架自身仓库"这一真实场景仍有价值——框架自身的源码就分布在上述两套布局中,检测判定在该场景下是有效输入而非噪声。

四、回归测试设计:缺陷签名 + 孤儿消费者双重防线

tests/bug-3290-intel-updater-layout-block.test.cjs 是该修复的行为契约测试,注意其文件头声明的立场(第 1–3 行):agents/gsd-intel-updater.md 本身就是"部署产物"——它是交付给智能体的指令集,因此断言其文本内容就是在测试部署行为契约。测试分两组:

Group A — 门控契约(第 61–111 行):用正则 /ls -d \.kilo\b.*\|\|.*echo "?unknown"?/ 提取"缺陷签名"——那个无条件执行、会输出判定的 shell 单行。若签名缺席(块已删除),通过;若签名存在,则要求文件内容中存在框架仓库守卫(get-shit-done-ccis-this-the-frameworkOnly run 等语义标记之一),否则以完整的修复示例(含 if [[ "$(jq -r ... 写法)给出失败信息。

Group B — 无孤儿下游消费者(第 113–187 行):递归扫描 agents/commands/gsd/get-shit-done/workflows/ 三个目录的全部 Markdown 文件,断言:

  1. 没有任何文件包含哨兵短语 Layout detection returned(这是那行吵闹输出的指纹);
  2. 除产生方 gsd-intel-updater.md 自身外,没有任何智能体或工作流指令去消费该判定输出(模式 Layout detection returned.*(unknown|claude|kilo))。

第二组的意义在于:只要存在任何下游消费者,"删除该块"就会破坏功能,只能走"门控"路线——测试甚至在其失败信息里写明 If a consumer exists, use option A (gate) not option B (remove).,把方案选择逻辑固化进了断言本身。

五、发布时的 changeset 消费流程

type: Removed 的 sunny-ibex-wave 片段在发布时会被统一消费。.changeset/README.md 给出的发布命令:

node scripts/changeset/cli.cjs render --version vX.Y.Z --date YYYY-MM-DD

该命令读取全部片段,按 type: 分组生成条目,把 ## [Unreleased] 替换为新的 ## [vX.Y.Z] - YYYY-MM-DD 区块,在其上方新开一个空的 ## [Unreleased],并删除已消费的片段文件,全程幂等。仓库中 scripts/changeset/ 目录下的 new.cjscli.cjs 等脚本即为该工具链的实现,相关行为由 tests/changeset-new.test.cjstests/changeset-render.test.cjstests/changeset-lint.test.cjs 等测试覆盖。

六、要点回顾

  • 片段格式:frontmatter(type + pr)+ 一句用户可见变化描述;type 取 Keep a Changelog 六值之一;用 node scripts/changeset/new.cjs 生成,发布时由 node scripts/changeset/cli.cjs render 合并进 CHANGELOG(见 .changeset/README.md)。
  • 本次修复gsd-intel-updater 的布局检测 bash 块被门控在 package.json name == "get-shit-done-cc" 的正向检查之下,普通项目静默跳过,不再输出残留的 "Layout detection returned 'unknown'" 行(片段原文 + agents/gsd-intel-updater.md)。
  • 验证方式:回归测试以"缺陷签名正则 + 守卫语义检查 + 孤儿消费者全库扫描"三层结构锁住该行为(tests/bug-3290-intel-updater-layout-block.test.cjs)。
  • 适用前提:以上行为对应当前仓库 package.json1.50.0-canary.0 版本下的智能体指令集;对 GSD 框架自身仓库运行 map-codebase --query 时,布局检测仍会按 kilo / claude 两种规范布局解析源路径。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389