news 2026/9/29 3:02:09

gsd-core 修复解读:3381 修复 —— /gsd-verify-work --ws 通过 SDK 解析工作流阶段

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gsd-core 修复解读:3381 修复 —— /gsd-verify-work --ws 通过 SDK 解析工作流阶段

【免费下载链接】gsd-core

Git. Ship. Done - Core

项目地址:https://gitcode.com/gh_mirrors/ge/gsd-core
点击查看免费下载

本篇文章基于 .changeset/archived/fix-3381-init-verify-work-ws.md(type: Fixed,PR #3386)展开,剖析 gsd-core 中/gsd-verify-work --ws <name>的缺陷根因、修复实现与回归验证。读完本文,你将理解工作流(workstream)模式下阶段验证的目录作用域问题,掌握init.verify-work、MVP 模式查询与阶段目标查询如何接收到选中工作流,从而不再错误回退到根目录.planning/。

一、变更速览:一条 changeset 背后的问题

该 changeset 全文只有一句话,却指向一个真实且影响面明确的缺陷:

/gsd-verify-work --ws <name>now resolves workstream phases through the SDK—init.verify-work, MVP-mode lookup, and phase-goal lookup all receive the selected workstream instead of falling back to root.planning/.

拆解这句话可以得到三个事实:

  1. 修复对象是命令/gsd-verify-work --ws <name>,即在指定工作流(workstream)中对某个阶段执行验证;
  2. 修复方式是"通过 SDK 解析工作流阶段"——即由 gsd-core 的查询命令(query init.verify-work等)承担阶段解析,而不是让工作流脚本自行猜测路径;
  3. 修复涉及三个查询点:init.verify-work(初始化阶段上下文)、MVP 模式查询(phase.mvp-mode)、阶段目标查询(roadmap.get-phase);修复前它们会回退到根目录.planning/,修复后都接收到用户选中的工作流。

这条修复之所以成立,需要先理解两个背景:/gsd-verify-work命令本身,以及 gsd-core 的工作流(workstream)目录作用域模型。

二、背景:/gsd-verify-work 与工作流作用域

2.1 verify-work 命令是做什么的

命令契约定义在 commands/gsd/verify-work.md 中,其 frontmatter 声明:

name: gsd:verify-work description: Validate built features through conversational UAT argument-hint: "[phase number, e.g., '4'] [--ws <name>]" requires: [execute-phase, phase]

它的职责是"通过会话式 UAT 验证已构建的功能":一次一个测试、纯文本回答、不搞审问式提问;发现问题后自动诊断、规划修复并为执行做准备。输出为{phase_num}-UAT.md测试结果追踪文件,若发现问题则产出已诊断的差距与可直接交给/gsd:execute-phase的修复计划。命令本身可带两个参数:阶段号(如4)与--ws <name>工作流名。

2.2 工作流模式的目录作用域

gsd-core 在项目根.planning/之外支持多工作流布局。从 src/init.cts 的相关注释与实现可以看到:

  • 每个工作流拥有自己的规划根:.planning/workstreams/<ws>/,其中phases/、ROADMAP.md、STATE.md、REQUIREMENTS.md都是工作流作用域的(workstream-scoped);
  • 例外是PROJECT.md,它是跨工作流共享的("PROJECT.md is shared across workstreams",见 src/init.cts 中cmdInitCompleteMilestone相关注释);
  • planningDir(cwd)是"工作流感知"的:当存在激活的工作流时,它解析到该工作流的规划目录,而不是根.planning/。

这里的关键机制是GSD_WORKSTREAM环境变量。从 src/init.cts 的注释可以确认:显式传入--ws会设置GSD_WORKSTREAM,从而满足工作流模式的检查;而没有激活工作流又没有--ws时,planningDir(cwd)会解析到根.planning/——这正是"静默报告一个过期的根里程碑"的危险路径。

三、缺陷根因:--ws 未被 SDK 查询消费

修复前的缺陷链条如下:

  1. 用户在/gsd-verify-work --ws <name>中显式指定了工作流;
  2. 但工作流脚本(gsd-core/workflows/verify-work.md)没有从$ARGUMENTS中提取--ws并转发给下游 SDK 查询;
  3. 于是GSD_WORKSTREAM从未被设置,planningDir(cwd)继续解析到根.planning/;
  4. 结果是:init.verify-work的阶段查找、phase.mvp-mode的 MVP 模式判定、roadmap.get-phase的阶段目标读取,全部落在错误的目录上——要么找不到工作流内的阶段(阶段在.planning/workstreams/<ws>/phases/下),要么读到根目录的同名阶段/目标,产生"张冠李戴"的验证上下文。

从 src/init-command-router.cts 的注释也能印证这条边界:--ws在发布的工作流中指向独立的query init.verify-work查询接口(seam),并在到达init verify-work命令族之前被剥离。也就是说,--ws的消费点本来就在查询层,工作流若不在调用查询时把它带上去,它就彻底丢失。

四、修复的工程实现:三层收口

修复将--ws从"用户参数"一路收口到"SDK 查询参数",共三层。

4.1 工作流层:从 $ARGUMENTS 提取 --ws 并派生阶段参数

gsd-core/workflows/verify-work.md 的initialize步骤现在包含以下解析逻辑:

GSD_WS="" echo "$ARGUMENTS" | grep -qE -- '--ws[[:space:]]+[A-Za-z0-9._-]+' && GSD_WS=$(echo "$ARGUMENTS" | grep -oE -- '--ws[[:space:]]+[A-Za-z0-9._-]+') PHASE_ARG=$(echo "$ARGUMENTS" | sed -E 's/--ws[[:space:]]+[A-Za-z0-9._-]+//g' | xargs) INIT=$(gsd_run query init.verify-work "${PHASE_ARG}" ${GSD_WS})

要点:

  • GSD_WS默认置空;只有当$ARGUMENTS中出现--ws <name>形态时才提取整对 token(--ws连同工作流名)作为GSD_WS;
  • PHASE_ARG通过sed删除--ws <name>后经xargs去空白得到,保证阶段号参数纯净;
  • 随后query init.verify-work "${PHASE_ARG}" ${GSD_WS}把工作流名原样转发给 SDK 查询(GSD_WS展开后即--ws <name>两个 token,未加引号以正确分词)。

值得注意的细节:--ws值的工作流 slug 字符类被刻意收窄为[A-Za-z0-9._-]+(而非宽泛的[^[:space:]]+),因为工作流 slug 由这些字符构成,收窄可以避免误吞后续参数,也保证了GSD_WS能可靠到达每一个工作流敏感的查询。

4.2 SDK 查询层:init.verify-work 接收工作流并解析阶段

query init.verify-work由 src/init.cts 的cmdInitVerifyWork实现。收到带工作流作用域的cwd后,它通过共享原语解析阶段:

const config = loadConfig(cwd); let phaseInfo = guardedFindPhase(cwd, phase, config.project_code); const roadmapPhase = guardedGetRoadmapPhase(cwd, phase, config.project_code); phaseInfo = applyRoadmapFallback(phaseInfo, roadmapPhase, (rp) => { /* 合成回退对象 */ });
  • guardedFindPhase(src/init.cts)封装findPhaseInternal,并附加#2056外来前缀防护:当查询携带了项目代码前缀而阶段不匹配时返回null;
  • guardedGetRoadmapPhase是对路线图阶段读取的同等防护封装;
  • applyRoadmapFallback(src/init.cts)是归档/未命中回退:若磁盘阶段已归档而路线图仍有记录,则置空;若磁盘未命中而路线图命中,则用路线图合成阶段信息(phase_number、phase_name、phase_slug、空plans/summaries等)。该共享回退同样被execute-phase、plan-phase、code-review、review等命令复用,保证行为一致。

在拿到阶段信息后,cmdInitVerifyWork继续组装验证上下文:

  • phase_dir、phase_number、phase_name、has_verification;
  • state_path/roadmap_path:经由工作流感知的planningDir(cwd)解析(STATE.md、ROADMAP.md),供verify-work.md的plan_gap_closure步骤读取,而不是硬编码根.planning/字面量(对应#2376的修复);
  • phase_completion:内含buildPhaseCompletionProjection的结果(implementation_complete、verification_status、verification_passed、phase_complete、verification_next_action、verification_next_command等),以及 UAT 状态(uat_passed、uat_blockers、ready_to_transition);
  • ui_phase_active与section_manifest:供 UI 验证与"mvp-uat-framing"小节门控使用。

正因为GSD_WS(即--ws <name>)被传到了这条查询链路,GSD_WORKSTREAM得以生效,planningDir(cwd)解析到.planning/workstreams/<ws>/,findPhaseInternal才能在正确的作用域下找到阶段目录——修复前这一步恰恰回退到了根.planning/。

4.3 作用域查询:MVP 模式与阶段目标

除了初始化查询,工作流还把工作流转发给另外两个查询:

# MVP 模式检测:集中式 phase.mvp-mode 解析器 MVP_MODE=$(gsd_run query phase.mvp-mode "${phase_number}" ${GSD_WS} --pick active)

以及回归测试断言中的阶段目标查询:

gsd_run query roadmap.get-phase "${phase_number}" ${GSD_WS} --pick goal
  • phase.mvp-mode判定"当前阶段是否为 MVP 模式"。修复前它读取根.planning/下路线图中的**Mode:** mvp标记,工作流内阶段会得到错误答案;修复后工作流被转发,模式判定按工作流作用域进行。工作流注释还说明:verify-work没有--mvp命令行开关,模式从已规划阶段继承,因此查询省略--cli-flag,走 roadmap → config → false 的回落链。
  • roadmap.get-phase提取阶段目标(goal)。其解析依据位于 src/roadmap-parser.cts,通过**Goal:**区块正则提取目标文本。该查询在verify-work的verify_phase_goal步骤中被消费——验证器(gsd-verifier)需要拿到正确的阶段目标与需求 ID 才能核对实现是否达标。

三个查询全部拿到GSD_WS,正是 changeset 中"init.verify-work、MVP-mode lookup、phase-goal lookup all receive the selected workstream"的落地形态。

五、验证结果如何被路由:verification 状态机

阶段解析正确之后,验证结果本身由 src/verification.cts 统一裁决。该模块是验证状态路由的唯一事实源,定义在VERIFICATION_ROUTING_TABLE(src/verification.cts):

status语义推荐下一步
passed验证通过继续
gaps_found发现差距运行plan-phase <N> --gaps规划修复,重新执行后再发布
human_needed需要人工验证完成*-UAT.md中的手工测试后重跑verify-work
stale覆盖的源文件在验证后发生了变化重跑execute-phase(在验证门处恢复并重新运行验证器,刷新 VERIFICATION.md 与摘要)
missing无验证报告运行execute-phase是安全的(不会重跑已有 SUMMARY.md 的计划)
unparseable报告 frontmatter 不是合法 YAML直接修复报告中的语法错误(重跑 execute-phase 无法修复)
unknown非标准的自定义状态若是手工标记则无需处理,否则运行execute-phase重新生成验证

其中passed/gaps_found/human_needed是验证器(gsd-verifieragent)真正会写出的值(VERIFIER_STATUSES);stale/missing/unparseable/unknown是内部构造的哨兵状态。next_command统一经过formatGsdSlash投影为当前运行时的命令形态(如/gsd-execute-phase、$gsd-execute-phase),避免硬编码废弃的/gsd:冒号形式。

readVerificationStatus只读取*-VERIFICATION.mdfrontmatter中的status(解析器锚定在文件字节 0,正文里的status:不会误读),并支持#4155引入的覆盖输入指纹(covered_files+covered_digest)作为比 mtime 更强的过期判定依据。这些路由结果最终通过cmdInitVerifyWork的phase_completion暴露给工作流,驱动 UAT 会话与差距闭环。

六、回归测试:--ws 转发链路被锁死

修复不是只改脚本了事,还配了回归测试。当前测试位于 tests/verify-work-auto-transition.test.cjs,标题即bug #3381: verify-work forwards workstream context,测试注释说明它由tests/bug-3381-verify-work-workstream.test.cjs折叠而来(合并史诗 #1969)。

该测试用正则逐条断言工作流源码中必须存在的转发契约:

assert.match(workflow, /GSD_WS=""/, 'verify-work must initialize GSD_WS'); assert.match(workflow, /grep -qE -- '--ws[[:space:]]+[A-Za-z0-9._-]+'/, 'verify-work must detect --ws in $ARGUMENTS'); assert.match(workflow, /grep -oE -- '--ws[[:space:]]+[A-Za-z0-9._-]+'/, 'verify-work must extract the --ws flag pair from $ARGUMENTS'); assert.match(workflow, /PHASE_ARG=\$\(echo "\$ARGUMENTS" \| sed -E 's\/--ws[[:space:]]+[A-Za-z0-9._-]+\/\/g' \| xargs\)/, 'verify-work must derive PHASE_ARG after removing --ws'); assert.match(workflow, /gsd_run query init\.verify-work "\$\{PHASE_ARG\}" \$\{GSD_WS\}/, 'init.verify-work must receive GSD_WS so phase_dir resolves in workstreams'); assert.match(workflow, /gsd_run query phase\.mvp-mode "\$\{phase_number\}" \$\{GSD_WS\} --pick active/, 'phase.mvp-mode must receive GSD_WS so roadmap mode is workstream-scoped'); assert.match(workflow, /gsd_run query roadmap\.get-phase "\$\{phase_number\}" \$\{GSD_WS\} --pick goal/, 'roadmap.get-phase must receive GSD_WS so goals are workstream-scoped');

这份断言同时锁死了三类东西:

  1. 解析逻辑:GSD_WS初始化、--ws检测与提取、PHASE_ARG的派生(sed删除--ws <name>对);
  2. 转发对象:三个工作流敏感查询必须无一遗漏地收到GSD_WS;
  3. 语义承诺:注释明确写明了每条断言的动机——init.verify-work收到GSD_WS才能让phase_dir在工作流内正确解析;phase.mvp-mode收到它路线图模式才是工作流作用域;roadmap.get-phase收到它目标才是工作流作用域。

任何未来的重构若删掉其中一条转发,测试就会立刻失败,从而防止缺陷 #3381 以"回归"形式复活。

七、使用方式与适用前提

修复后的命令形态与使用方式如下:

# 在根项目上验证阶段 4 /gsd-verify-work 4 # 在指定工作流 my-ws 中验证阶段 4(本次修复的核心场景) /gsd-verify-work 4 --ws my-ws

工作流 slug 由[A-Za-z0-9._-]字符构成,--ws与工作流名之间需以空白分隔。适用前提与限制:

  • 该命令依赖 gsd-core 的 SDK 查询能力(gsd_run query ...),需要已完成 gsd-core 安装并在$ARGUMENTS中携带阶段号或存在活跃会话;
  • 工作流模式要求显式工作流:无活跃工作流且未传--ws时,planningDir(cwd)解析到根.planning/是旧行为,请务必显式指定;
  • 本修复保证的是"工作流内阶段解析正确",验证的裁决仍遵循 src/verification.cts 的状态机(passed/gaps_found/human_needed等),UAT 输出仍是{phase_num}-UAT.md;
  • 差距闭环路径不变:发现问题后plan_gap_closure步骤使用{state_path}、{roadmap_path}(二者已由工作流感知的planningDir(cwd)解析)拉起gsd-planner --gaps生成带gap_closure: true与gap_ids的计划,供后续verify-work恢复时对账。

结语

fix-3381-init-verify-work-ws.md是一条"小而完整"的修复:它把一个命令参数(--ws)通过工作流脚本的提取、SDK 查询的转发、GSD_WORKSTREAM的作用域生效,最终传导到三个查询点(init.verify-work、phase.mvp-mode、roadmap.get-phase),彻底消除了"用户明明指定了工作流、SDK 却读根.planning/"的静默错误。若你的项目使用 gsd-core 的多工作流模式并在工作流内执行阶段验证,请确认版本包含此修复(PR #3386),并在调用时始终显式传递--ws <name>。

【免费下载链接】gsd-core

Git. Ship. Done - Core

项目地址:https://gitcode.com/gh_mirrors/ge/gsd-core
点击查看免费下载
上一篇:gh_mirrors/es/es6features实战:对象属性遍历方法对比
下一篇:7步实现Druid监控数据持久化:从日志到MySQL的无缝方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 23:39:42

铁路轨道缺陷数据集:VOC标注转YOLO格式的裂缝与间隙检测指南

简介&#xff1a;铁路轨道缺陷检测数据集&#xff0c;面向计算机视觉目标检测研究者与智慧铁路维护工程师&#xff0c;旨在训练可自动识别轨道裂缝、间隙等缺陷的模型。压缩包为zip格式&#xff0c;内共2000个文件&#xff0c;全部为PASCAL VOC XML格式的标注数据&#xff0c;包…

作者头像 李华
网站建设 2026/9/27 23:39:28

wordpress图片变大图解步骤与避坑指南

wordpress图片变大图解步骤与避坑指南 找建站公司怕被坑高价?别急,很多看似复杂的服务器问题,其实自己花半小时就能搞定,省下那几千块外包费。今天专门拆解【wordpress图片变大】这个高频痛点,配合清晰的【图解步骤】,让你像老手一样掌控服务器细节,不再为虚高报价买单。…

作者头像 李华
网站建设 2026/9/27 23:39:21

外贸做消防的网站实战案例:避坑指南与前端规范

外贸做消防的网站实战案例:避坑指南与前端规范 上周刚帮一个做出口消防设备的客户紧急处理完一场危机。他们的新站刚上线三天,后台突然收到大量垃圾询盘,首页还莫名其妙挂上了境外博彩链接。老板急得在群里喊救命,问网站被黑挂马不知道怎么办。这种场景在外贸建站圈太常见了,尤其是刚起步的小微企业。…

作者头像 李华
网站建设 2026/9/27 23:39:13

搞定wordpressmd主题:5个图解步骤让官网流量翻倍

搞定wordpressmd主题:5个图解步骤让官网流量翻倍 网站做好了没人访问,这是建站圈最扎心的现实。很多老板花几万块做完了官网,上线三个月后台全是零,问就是“百度不收录”。其实问题往往出在最基础的主题配置上,尤其是WordPress…

作者头像 李华
网站建设 2026/9/27 23:38:49

中国有几家网络公司?用3个免费工具拆解流量真相

中国有几家网络公司?用3个免费工具拆解流量真相 域名服务器搞不懂,是很多刚入行或接手新盘子的运营最头疼的事。明明网站上线了,后台数据却一片惨淡,或者刚花大价钱买的域名,第二天因为备案问题直接打不开。这时候,盲目去问那些所谓的“大牛”往往得不到实在答案,反而容易踩坑。其实,搞清楚“中国有几家网络公司”…

作者头像 李华