Serial Studio 的 /ss-implement:规格驱动开发中"实现阶段"的完整执行纪律
【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio
在 Serial Studio 这个 Qt 遥测仪表板项目中,/ss-implement是规格驱动(spec-driven)四阶段工作流的最后一个环节,也是唯一允许写代码的阶段。它以一份经维护者批准的tasks.md检查清单为契约,逐任务执行、逐项验证,并通过热路径规则、风格校验脚本与反事实自审把"AI 写代码"约束在可审查的轨道上。读完本文,你能理解这套实现阶段的前置条件、单任务循环的五步操作、范围纪律与完成门禁(Definition of Done),并掌握code-verify.py、sanitize-commit.py等验证工具在实现流程中的具体用法。
四阶段工作流中的位置:从契约到执行
/ss-implement不是孤立的编码指令,它位于 spec-driven.md 定义的spec -> plan -> tasks -> implementation流水线末端。该文档将四个阶段整理为如下门禁(Gate)结构:
| 阶段 | 技能 | 产出 | 门禁 |
|---|---|---|---|
| 1. 规格 | /ss-spec | spec.md—— WHAT & WHY:问题、目标、非目标、编号需求、验收标准、约束 | 维护者标记 spec 为approved |
| 2. 计划 | /ss-plan | plan.md—— HOW:受影响文件、数据流、热路径/线程影响、取舍、风险、测试计划 | 维护者批准设计 |
| 3. 任务 | /ss-tasks | tasks.md—— 有序、可独立验证的检查清单 + Definition of Done | 维护者批准任务拆分 |
| 4. 实现 | /ss-implement | 逐任务落地的代码;tasks.md保持实时更新 | Definition of Done 达成;自审;sanitize |
三个阶段的文档存放在doc/claude/specs/NNNN-slug/目录中,编号规则与状态生命周期见 specs/README.md:编号为四位零填充、单调递增且永不复用;spec.md的status:字段遵循draft -> approved -> in-progress -> done | shelved的生命周期,其中in-progress正是/ss-implement进入时设置、完成时改为done的两个状态。
这种设计的核心动机在 spec-driven.md 中说得直白:契约从"Agent 是否猜对了"变成"我们在代码存在之前是否已书面达成一致"。方案错误可以在plan.md阶段以零成本被否决,而不是在 600 行 diff 里被发现。
前置条件:进入实现阶段之前的三道检查
SKILL.md 的 Preconditions 部分规定了进入实现阶段必须满足的三个条件:
检查单已批准:
doc/claude/specs/NNNN-slug/tasks.md必须存在,且其 frontmatter 中status:为approved。对照任务模板 templates/tasks.md 可以看到这个门禁的原始写法:--- spec: NNNN-short-slug phase: tasks status: draft # draft -> approved (gate before /ss-implement) updated: YYYY-MM-DD ---模板顶部还有一条显式门禁声明:"Gate: do not start
/ss-implementuntil a human marks thisapproved."完整阅读三份文档:在碰任何代码之前,必须通读
spec.md、plan.md、tasks.md。这不是客套话——spec.md提供验收标准(验收标准必须全部达成并在spec.md中勾选),plan.md提供文件清单(即本次改动的工作范围),tasks.md提供执行顺序。切换规格状态:将
spec.md的status:置为in-progress。这个动作使规格目录本身成为"正在进行中"的活记录,任何其他会话只读三个文件就能判断当前状态。
单任务循环:五步操作及其原理
技能文档的主体是一个"per-task loop"——对tasks.md中的每个任务按顺序执行五步。下面逐步拆解,并解释每步背后的机制。
第 1 步:先读后写(Read before writing)
本会话内必须先完整读取目标文件。文档特别点名了两类强制全量阅读的对象:
- 热路径文件:
FrameBuilder、CircularBuffer、FrameReader、Dashboard(对应 code-style.md Performance 一节中"仪表盘路径永不分配、永不拷贝 Frame"的性能规则); - 已有的 signal/slot 接线。
同时,涉及热路径的任务必须先调用ss-hotpath技能;编写非平凡新 C++ 时调用ss-cpp-modern。之所以强调"本会话内完整读取"而非依赖摘要,与 j-space.md 阐述的工作空间机制有关:自动模式(模式匹配式的编辑)恰恰是静默破坏(silent-breakage)规则被违反的高发区,完整阅读是进入审慎模式的必要中断。
第 2 步:命名绑定不变量(Name the binding invariants)
在第一次Edit之前,必须用自己的话在聊天中复述该任务 Does 行所承载的不变量,以及阅读代码时新发现的不变量。文档给出了理论依据:
"A constraint steers the edit only when named at the point of action, not when it sits in a doc you read earlier"(约束只有在动作发生点被命名时才能引导编辑,而不是躺在你早先读过的文档里)。
这一点在 j-space.md 的"六项纪律"中有完整展开:模型可言语化的表征才进入"全局工作空间"参与灵活计算;上下文里 200 行之前的规则只是背景文本,可能永远不会被激活。配套设计上,ss-tasks 要求在任务拆分阶段就把不变量写进每个任务的 Does 行,/ss-implement在编辑时只需"重述"而非"重新发现"。
一个真实案例见 0085-native-publish-allocation-free 的 tasks.md:其 Conventions 部分写着"Every task onBlockStager.*orFrameBuilder.cppis hotpath: read the file in full first, invokess-hotpath, and restate the invariant named in the task's Does line before editing."(每个触及BlockStager.*或FrameBuilder.cpp的任务都是热路径任务:先完整读文件、调用ss-hotpath、编辑前重述 Does 行中的不变量。)
第 3 步:用定向 Edit 做修改(Make the change)
要求"edit, don't rewrite"——用精确定向编辑而非重写整个文件,并遵循 code-style.md 的硬性风格约束。与实现阶段直接相关的要点包括:
- 头文件成员排序(
Q_OBJECT→Q_PROPERTY块 →signals:→ 私有构造/删除拷贝移动 →public:→ slots → 私有辅助 → 私有成员); - 所有非 void 返回值加
[[nodiscard]]; - 禁止头文件内成员初始化(
int m_foo = 0;被禁止,用构造初始化列表); - 信号用
Q_EMIT,绝不用裸emit; - 函数体内禁止注释(in-body comments),98 字符
//---横幅只用于函数之间; - 100 列上限;源码 ASCII-only。
这些规则由scripts/code-verify.py强制执行,下一步会看到。
第 4 步:验证任务(Verify the task)
每个任务的验证分两层:
- 风格/规则校验:
python scripts/code-verify.py --check <changed files>。该脚本是 code-style.md 的执行体("read its--checkoutput, don't re-derive the rules")。新产生的错误必须在进入下一任务前解决;advisory(建议级)属于基线债务,但新代码必须清零。从源码看,--check参数在 code-verify.py 中定义为 "report only, no writes"(只报告、不写入),与--fix路径明确区分,这正是实现阶段"只报告"而提交前"才修复"的分工基础。文档还指出它内置了一组perf-*建议级检查,专门捕捉热路径上的意外内存分配、正则构造、加锁、日志、抛异常等模式。 - 任务声明的检查:运行
tasks.md中该任务 Verify 行写明的检查——可能是你可以运行的tests/scripts/JS 单元测试,或一次回读(read-back)。
以真实任务的 Verify 行为例,spec 0085 的 T1 写明:
- **Verify:** `python scripts/code-verify.py --check core/Core/DataModel/Frame.h`。第 5 步:勾选完成(Mark it done)
在tasks.md中把该任务的复选框勾上,使该文件保持"活记录"(live record)。这是 j-space.md 第 6 条纪律"外部化以释放容量"的直接落地:中间状态写入持久工件,后续只需重新加载与当前动作绑定的那部分,多约束的长任务不必"记在脑子里"。
范围纪律:plan 的文件清单就是车道
per-task 循环之外,文档有两条范围红线:
- 严格停留在 plan 的文件清单内。若发现需要的改动超出清单,停下来在聊天中命名它("the plan didn't cover X — add it?"),而不是悄悄扩大 diff;
- 绝不触碰、回滚或恢复任何本会话未编辑过的工作区文件。
这两条与 spec-driven.md 的"Trust Contract"小节一一对应:"the plan's file lististhe lane. Anything outside it is named in chat, not slipped into the diff."(plan 的文件清单就是车道,清单之外的改动要么在聊天中命名,要么不进 diff。)其动机同样来自规格文档的门禁纪律:如果实现暴露了计划缺漏,正确动作是回退、修订plan.md/tasks.md并重新确认,而不是静默偏离——"a stale spec is worse than none"(过期的规格比没有规格更糟)。
完成门禁:Definition of Done 的六个动作
当所有任务勾选完毕,按tasks.md中的 Definition of Done 执行收尾。技能文档列出的六个动作如下:
- 静态审查:对 C++ diff 调用
qt-cpp-review技能,处理或备注发现的问题。该技能带有一组命名审查任务("six named missions",见 j-space.md 中"Named lenses"纪律的接线表)。 - 热路径确认:若改动触及热路径,与维护者确认
--benchmark-hotpath计划。技能明确说明 Agent "cannot run it — you don't build the app"(你无法运行它——你不构建应用),这与后文"永不构建/运行应用"的规则一致。 - 反事实自审(counterfactual self-review):先问"这是被要求的改动,且仅此而已吗?",然后大声回答:"这个 diff 最可能违反哪条规则?具体证据是什么?"——必须点名规则和证据,禁止"看起来没问题"式的泛泛通过。若任何一问的回答薄弱,必须在宣称完成之前承认。这正是 j-space.md 第 4 条纪律在实现阶段的接线点。
- Sanitize:运行
python scripts/sanitize-commit.py。从 sanitize-commit.py 的头部注释可以看到其完整流水线:规范化文件权限、Doxygen 注释扩展、两次 clang-format 夹一次code-verify.py --fix、可选 clang-tidy、全局状态与翻译单元尺寸 ratchet 检查(均为 blocking)、black 格式化 Python、文档 AI 叙述扫描、claim-verify.py对照源码校验文档声明(blocking)、重新生成 SDK 绑定与属性注册表并做漂移门禁等。技能文档特别强调它"sanitizes only — never commits"(只做净化,绝不提交)。 - 识别 pytest 目标:从
plan.md中识别出需要维护者运行的pytest集成测试,并提醒前提条件——应用必须以 API server 启用状态运行。 - 收口状态:将
spec.md的status:置为done。
模板 templates/tasks.md 的 Definition of Done 一节给出了这套门禁的完整清单形态:
## Definition of Done - [ ] Every acceptance criterion in `spec.md` is met and checked off there. - [ ] `python scripts/code-verify.py --check` is clean on all changed files (no new errors). - [ ] `qt-cpp-review` run on the C++ diff; findings addressed or noted. - [ ] `ss-hotpath` checks pass / `--benchmark-hotpath` not regressed (if hotpath touched). - [ ] Relevant `pytest` tests identified for the maintainer to run (listed in `plan.md`). - [ ] `python scripts/sanitize-commit.py` run; working tree clean of lint debt. - [ ] Diff is *what was asked, and only that* — no scope creep, no foreign files touched. - [ ] `spec.md` status set to `done`.红线规则:权限边界与"规格即契约"
SKILL.md 末尾的 Rules 一节定义了/ss-implement的三条不可妥协规则:
- 永不构建或运行应用;永不在没有逐轮明确许可的情况下 commit 或 push——此前的授权不跨轮次延续("earlier authorizations do not carry over")。这也是它与
sanitize-commit.py的分工边界:净化脚本刻意不含提交动作,提交权限始终留在人手里。 - 规格即契约:
spec.md的每条验收标准最终都必须在其中被满足并勾选。若构建过程中现实偏离计划,停下并修订plan.md/tasks.md(重新确认),而不是静默即兴发挥。 - 让
tasks.md保持诚实:一个做了一半的功能,应当只靠读三个规格文件就能被另一个会话(或另一个人)接管。
完整案例:spec 0085 的任务执行记录
仓库中 0085-native-publish-allocation-free/tasks.md 是/ss-implement工作方式的完整实例。它的结构展示了模板约定在真实功能中的应用:
- frontmatter:
spec: 0085-native-publish-allocation-free、phase: tasks、status: approved、updated: 2026-09-11——approved状态意味着/ss-implement已获准执行; - Conventions 部分写死了本功能的执行约定:热路径文件清单(
BlockStager.*、FrameBuilder.cpp)、消费者先于生产者落地("Consumers (T4) land before the producer flips the rule (T5, T6), so the tree never has a block a consumer misreads"),保证树在任何中间状态都不会出现消费者误读的块; - 每个任务(T1、T2、...)都包含Files(精确到文件,并注明迁移原因,如 "
Frame.halready sits over the TU cap")、Does(一两句话,且不变量直接写在其中)、Verify(code-verify --check <具体文件>)、Deps(依赖的任务号)、以及- [x] done勾选状态——这些被逐个勾掉的复选框,正是"live record"纪律的物理形态。
小结:实现阶段为什么长这样
把 SKILL.md 的五步循环、范围纪律与完成门禁放回 spec-driven.md 的视角,可以提炼出/ss-implement的设计逻辑:
- 门禁串行化:
approved -> in-progress -> done的状态迁移把"人批准"固化进文件本身,Agent 无法绕过门禁推进; - 约束临近动作点加载:热路径全量阅读 + 编辑前重述不变量,把 j-space.md 的"verbalize to load"从理论变成操作规程;
- 验证前置到每个任务:
code-verify.py --check逐任务跑,错误不累积;sanitize-commit.py与qt-cpp-review在收尾做整体把关; - 权限最小化:不构建、不运行、不提交,Agent 只产出工作区改动与已验证的检查记录,最终裁决权始终在维护者。
这套机制的适用前提值得说明:它面向的是 Serial Studio 这类对热路径性能与信号接线正确性高度敏感、且由 Agent 深度参与开发的大型 C++/Qt 代码库;对于单行修复、改名这类琐碎改动,spec-driven.md 明确建议跳过整个四阶段流程——"Forcing a four-phase ceremony onto a one-liner is its own kind of waste."(把四阶段仪式强加给单行改动本身就是一种浪费。)
【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考