【免费下载链接】gsd-core
Git. Ship. Done - Core
本文基于 GSD Core 仓库归档的 changeset
.changeset/archived/sunny-ibex-wave.md展开,讲解gsd-intel-updater(代码情报代理)如何通过「正向框架仓库门控」移除在普通用户项目上的无用布局检测输出,并深入其实现、回归测试与周边 intel 子系统。读完你不仅能复述这次变更,还能掌握 GSD Core 中「框架仓库专用逻辑必须显式门控」的工程范式,以及gsd-tools intel子命令的完整工作流。
变更概览:一条 "Removed" 类型的归档变更记录
归档文件 .changeset/archived/sunny-ibex-wave.md 的 frontmatter 只有两个字段:
--- type: Removed pr: 3299 ---正文是一句精确的变更描述(原文语义):
gsd-intel-updater不再在非 GSD 框架项目上输出一条残留的 "Layout detection returned 'unknown'" 提示—— 布局检测的 bash 块现在被一个正向的框架仓库检查门控(package.json的 name 字段匹配框架包名),普通用户项目会静默跳过该步骤。
这属于仓库 changeset 体系中的Removed类型:它不是新增功能,而是删除一段多余行为。归档目录意味着该变更已经合入并被移出待发布队列,它描述的是一个已经生效的修复。
问题本质:一段"死代码但会发声"的 bash 块
要理解这次修复,需要先还原修复前的行为。根据回归测试 tests/intel.test.cjs 中的注释(该测试由tests/bug-3290-intel-updater-layout-block.test.cjs折叠而来,对应 consolidation epic #1969):
gsd-intel-updater.md中的 "Runtime layout detection" 块此前在每个被分析的项目上无条件执行;- 它会在普通用户项目上打印:
Layout detection returned "unknown" — this project is not a GSD-system installation (no `.claude/gsd-core/` or `.kilo/` runtime root).问题在于这个判定结果在非 GSD 项目上根本不会被后续的 Step 2–6 使用。布局检测的唯一目的是:当被分析的项目正是 GSD 框架仓库自身时,检测运行时根目录(.kilo/或.claude/gsd-core/),从而在标准布局与.kilo布局之间选择规范路径。对普通用户项目而言:
- 该块是死代码(verdict 无人消费);
- 但它会产生噪音输出(vestigial line),污染每次代码情报更新的日志。
测试注释里把这种状态精确定义为"dead-but-noisy"(死了但还在吵),并给出了两种可接受的修复方向:
- 方案 A(门控):用框架仓库检查包裹检测块,使其只在分析 GSD 框架仓库自身时运行;
- 方案 B(删除):若确认没有任何下游消费者,则直接删除整个块。
修复落地:正向框架仓库门控(Option A)
当前仓库采用方案 A。在 agents/gsd-intel-updater.md 的 "Project Scope" 一节,布局检测块被一条 HTML 注释和一个if门控包裹:
# Only run layout detection when analysing the GSD framework repo itself. if [[ "$(jq -r '.name // ""' package.json 2>/dev/null)" == "@opengsd/gsd-core" ]]; then ls -d .kilo 2>/dev/null && echo "kilo" || (ls -d .claude/gsd-core 2>/dev/null && echo "claude") || echo "unknown" fi门控逻辑拆解:
| 组成 | 含义 |
|---|---|
jq -r '.name // ""' package.json | 从package.json提取包名,缺省时回退为空字符串,避免 jq 报错中断脚本 |
2>/dev/null | 静默吞掉 jq 不存在或 package.json 缺失时的错误 |
== "@opengsd/gsd-core" | 正向信号:仅当包名恰好等于框架包名时才继续 |
ls -d .kilo && echo "kilo" | 检测.kilo运行时根目录(优先级最高) |
(ls -d .claude/gsd-core && echo "claude") | 回退检测标准.claude运行时根目录 |
|| echo "unknown" | 兜底输出,但在门控内发生,不会污染普通项目 |
值得注意的是:归档 changeset 中描述的包名是get-shit-done-cc,而当前源码门控值是@opengsd/gsd-core。这并不矛盾——根据 docs/RELEASE-NOTES-LEGACY.md,get-shit-done-cc(以及后来的@opengsd/get-shit-done-redux)是项目更名前的旧包名,当前 package.json 中"name": "@opengsd/gsd-core"。即:门控始终检查"当前包名是否为框架本身",只是包名随项目演进更新了。这正是"正向门控"设计的关键——它锚定身份标识,而不是枚举"非框架"的否定条件。
布局检测的适用边界:只有框架仓库自身需要
门控之上,代理文档用一句注释明确了适用边界(agents/gsd-intel-updater.md):
Layout detection: only meaningful when analysing the GSD framework's own repo (#3290).
当被分析项目是GSD 框架仓库时,检测到的运行时根目录决定所有规范路径的解析,布局差异如下表:
| Source type | Standard.claudelayout | .kilolayout |
|---|---|---|
| Agent files | agents/*.md | .kilo/agents/*.md |
| Command files | commands/gsd/*.md | .kilo/command/*.md |
| CLI tooling | gsd-core/bin/ | .kilo/gsd-core/bin/ |
| Workflow files | gsd-core/workflows/ | .kilo/gsd-core/workflows/ |
| Reference docs | gsd-core/references/ | .kilo/gsd-core/references/ |
| Hook files | hooks/*.js | .kilo/hooks/*.js |
文档同时强调:检测到.kilo根后只能用.kilo布局路径,不要回退标准布局路径——否则统计组件数量(stack.json、arch-decisions.json中的 counts)时会拿到空目录,产出"语义为空"的情报。这解释了为什么布局检测必须在门控内运行:它在普通项目上没有任何正确路径可选,提前静默跳过是唯一合理行为。
回归测试:两组契约守卫修复不被回退
修复伴随的回归测试被折叠进 tests/intel.test.cjs,分为两组,恰好对应问题的两个侧面:
Group A —— 门控契约:断言"裸的无条件检测调用"不存在。测试用正则定位缺陷签名:
const bareDetectionPattern = /ls -d \.kilo\b.*\|\|.*echo "?unknown"?/;若该签名仍存在(说明块没被删),则继续断言必须存在框架门控信号(@opengsd/gsd-core、Only run、framework repo等任一命中)。两种合法状态——"块被完全删除"或"块被门控包裹"——都能通过测试。
Group B —— 无孤儿消费者:递归扫描agents/、commands/gsd/、gsd-core/workflows/三个目录下的所有 Markdown,断言:
- 没有任何文件包含噪音短语
Layout detection returned; - 除生产者
gsd-intel-updater.md自身外,没有任何代理或工作流指令去读取unknown/claude/kilo判定结果。
Group B 的存在很有工程意义:它验证了"这个 verdict 没有下游消费者",从而证明方案 A 的门控(而非保留一个仍被引用的输出)是正确选择。测试注释还给出了明确指引:如果将来出现消费者,就采用 Option A(门控)而不是 Option B(删除)。
周边上下文:intel 子系统与代理工作流
gsd-intel-updater不是孤立脚本,它处于 GSD 的 intel(代码情报)子系统内。这次静默化改动可以放在这个更大的上下文中理解:
- 能力注册:capabilities/intel/capability.json 将 intel 描述为"供代码库查询、diff、快照与 API 面提取的情报存储",暴露
gsd-tools intel子命令(query、status、update、diff、snapshot、patch-meta、validate、extract-exports、api-surface),并支撑/gsd-map-codebase命令与gsd-intel-updater代理。 - 激活门控:该能力由
intel.enabled配置键激活(activationKey字段),与gsd-intel-updater代理文档中 "Config Gate" 一节呼应——/gsd:map-codebase --query已确认intel.enabled为 true 才派发该代理。 - 三态解析:src/intel.cts 实现了一个三态解析器(installed + surfaced +
intel.enabled配置键),未激活时返回 "Intel system disabled. Set intel.enabled=true in config.json to activate."
这揭示了 GSD Core 的一贯风格:每个可能"只对特定环境有意义"的行为,都必须有显式的正向门控——框架仓库布局检测如此,intel 能力激活如此,运行时身份校验(runtime-identity,见 docs/FEATURES.md 中关于gsd-tools二进制冲突的记录)也是如此。
对用户与下游 Agent 的实际影响
对普通用户项目(绝大多数情况):
- 布局检测步骤静默跳过,不再产生任何 "Layout detection returned ..." 提示;
- 代理直接进入 Step 1(Orientation),行为与修复前完全一致——因为 verdict 本来就没被消费;
- 唯一可见差异是日志更干净、输出预算更省。
对GSD 框架仓库自身(如本仓库):
- 门控判定通过,布局检测照常运行,
.kilo/与.claude/gsd-core/根目录的区分逻辑不受影响; stack.json、arch-decisions.json中的组件计数仍按检测出的规范路径由Glob实时统计(agents/gsd-intel-updater.md 明确要求"计数必须来自 Glob,不能凭记忆或 CLAUDE.md")。
小结:一个可复用的"删除噪音"工程范式
这次变更虽然只有一句话,背后是完整的工程闭环:
- 识别 dead-but-noisy 行为——输出无人消费,却污染每个普通项目;
- 确认无下游消费者(Group B 测试)或补上正向门控(Group A 测试);
- 用身份锚定门控——
package.json的name等于框架包名,而非枚举排除条件; - 归档 changeset 并折叠回归测试,让修复可追溯、可防回退。
gsd-intel-updater的这次静默化,是"代码情报代理只对自身框架仓库做特殊处理,对普通项目保持安静"这一设计原则的典型样本。如果你在维护类似的代码情报/代码分析代理,这套"正向门控 + 无消费者断言 + 归档变更记录"的组合可以直接复用。
【免费下载链接】gsd-core
Git. Ship. Done - Core
相关推荐
gsd-core Codex 适配器 TEXT_MODE 回退机制:在 `request_user_input` 不可用时消除静默默认选择
gsd core Codex 适配器 TEXT_MODE 回退机制:在 request_user_input 不可用时消除静默默认选择 本文围绕 GSD Cor
wordfreq:颠覆性的40+语言词频分析专业级解决方案
wordfreq:颠覆性的40+语言词频分析专业级解决方案 你是否曾在多语言文本处理中为词频数据而烦恼?面对不同语言、不同数据源的词频信息,如何获取准确可靠的统
NLPget-shit-done Changeset 实战:解析 sunny-ibex-wave 片段与 gsd-intel-updater 布局检测门控修复(3290)
get shit done Changeset 实战:解析 sunny ibex wave 片段与 gsd intel updater 布局检测门控修复( 32
人工智能AI 应用提示工程开发工具工作流自动化AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考