Spec Coding Plus(规格驱动编程 · 改进版)
> Fork 说明:本技能从 SkillHub spec-coding v1.0.0 派生。保留其「模板即契约 + 状态机」优点,
> 补齐原版缺失的两块硬约束——Non-Goals 护栏 与 DoD 自动闸门(check_spec.py),
> 并修复状态机漂移、补「第四类」降级分支与下游闭环。
> 原安装包 ~/.workbuddy/skills/spec-coding 不修改(SkillHub 更新会覆盖)。
核心纪律(本版新增,用户 spec 方法论落地)
- Non-Goals 必写:每份 Spec 必须含「非目标 / Out-of-Scope」章节,显式列出本次不做的事,防范围 creep。这是规格写作最高 ROI 的补点。
- DoD 闸门必过:交付开发前运行
scripts/check_spec.py {spec}.md,任一硬闸门 FAIL(含缺 Non-Goals)→ 退出码 1,禁止交付。
核心工作流
场景 1:新项目生成规格文档
- 判断规格类型
- 功能需求 →feature-spec.md
- API 接口 →api-spec.md
- UI 组件 →component-spec.md
- 以上都不是(数据管道 / 算法 / Infra / 配置即代码等)→ 使用generic-spec.md通用骨架(仍须含 Non-Goals) - 生成草稿:读取模板 → 按需求填充各章节 → 必填 Non-Goals 章节 → 明确边界情况与验收标准
- 状态置顶:
状态: draft/创建日期/负责人(三字段缺一不可,闸门 G1/G2 校验) - DoD 闸门:
python scripts/check_spec.py {spec}.md→ 全部 PASS 才继续 - 流转:
draft →(用户评审)→ review →(批准)→ approved →(交付开发)→ in-progress → done
> ⚠ 场景 1 必须显式经过review中间态,不得从 draft 直接跳 approved。
场景 2:老项目逆向生成规格
- 读取源码,分析输入/输出/行为
- 对照模板填充已知项,未知项显式标
> ⚠️ 待确认:…… - 输出
review状态文档 - 仍须过 DoD 闸门:结构类闸门(Non-Goals 章节存在、表格结构齐)必须过;「待确认」项不计入 FAIL,但验收清单须列明待补项
下游闭环(本版修复断链)
原版仅口述「与落地执行子代理协作」,无机制。本版约定:
approved后,整份 Spec 即下游编码代理的输入契约。- 交付方式(任选):把 Spec 全文粘贴进 coding 会话首条消息;或存为
spec.md让编码代理读取。 - 验收阶段用同一 Spec 的「验收标准 Checklist」逐项核对,达成
done。
机器可读契约头(agent_contract)
把"下游粘贴即契约"升级为"结构化传参"——在 frontmatter 中加 agent_contract 块,
编码 agent 可直接 parse 输入字段名 与 验收命令,无需从自然语言重新推断。
结构(YAML 合法,支持注释):
agent_contract:
inputs:
- name: user_id # 字段名(与 §2 输入规格对齐)
type: string
required: true
source: 路径参数 /api/v1/users/{user_id}
acceptance:
- command: pytest tests/api/test_xxx.py
expect: "exit 0,含正常/边界/错误响应用例"
- command: python scripts/check_spec.py {this_spec}.md
expect: "OVERALL: PASS"
inputs[]:实现所需字段(name/type/required/source),agent 据此生成函数签名与参数校验。acceptance[]:可执行的验收命令(command + expect),agent 据此自测并判定done。- 四套模板头部均已内置该块示例;标杆见
assets/examples/feature-example.md。 check_spec.py会对agent_contract做建议项(ADV)检查(存在且含 inputs/acceptance 即 OK),不计入硬闸门,不阻塞交付。
轻量档(tier · 小需求减负)
小改动没必要写满八闸。Spec 在 frontmatter 加 tier: lite 即进入轻量档:
- 硬闸门只剩 4 道:G1(状态) / G2(负责人) / G7(验收 Checklist) / G8(错误·行为)。
- G3/G4/G5/G6 降级为建议项(ADV):Non-Goals、输入表、输出表、边界情况——写完更好,不写也不阻塞交付。
- 也可 CLI 强制:
python scripts/check_spec.py x.md --tier lite。 watch_gate/hook_gate自动读文件的tier字段,lite 档下硬闸全过即放行,无需改任何配置。
---
spec_type: generic
status: draft
owner: 张三
title: 修复导出按钮闪烁
tier: lite # ← 轻量档:只卡 G1/G2/G7/G8
---
精简模板见 assets/templates/minimal-spec.md(已内置 tier: lite),改个字段、修个 bug、补条配置直接用它,仪式感降到最低。
模板使用说明
读取模板前先判断需求类型:
| 模板文件 | 适用场景 | 默认档位 |
|---|---|---|
assets/templates/feature-spec.md |
业务功能、用户故事 | full |
assets/templates/api-spec.md |
REST API、GraphQL、Webhook | full |
assets/templates/component-spec.md |
React/Vue 组件、UI 控件 | full |
assets/templates/generic-spec.md |
数据管道/算法/Infra/配置等第四类 | full |
assets/templates/minimal-spec.md |
小改动/小需求,写满八闸嫌重 | lite |
规格状态流转
draft → review → approved → in-progress → done
draft: 草稿,待用户补充信息review: 待评审,等待用户确认(逆向生成默认此态)approved: 已批准,可交付开发in-progress: 开发中done: 已完成验收
> 模板头部状态字段须与以上五态对齐(原版 SKILL.md 内联示例漏「负责人」字段,本版已修正)。
输出原则
- 结构化优先 - 使用表格、代码块、列表
- 明确边界 - 必须列出所有边界情况和错误处理
- 可验收 - 每条规格都可被验证(是/否)
- 简洁 - 避免冗长描述,用示例代替解释
- Non-Goals 必写(full 档) - full 档每份 Spec 须含「非目标」章节;lite 档降为建议项
- 闸门不过不交付 -
check_spec.py硬闸门任一 FAIL 即退回补全(lite 档仅 G1/G2/G7/G8 硬卡)
DoD 闸门(scripts/check_spec.py)
硬闸门列表(任一 FAIL → 退出码 1,禁止交付):
| 闸门 | 校验内容 |
|---|---|
| G1 | 状态字段合法(draft/review/approved/in-progress/done),非占位 |
| G2 | 负责人字段存在且非占位(拒 [姓名]/待定/xxx 等) |
| G3 | 含 Non-Goals / 非目标 / Out-of-Scope 章节(full 档验实质内容,非空壳/仅"无") |
| G4 | 输入规格表有非占位数据行(full 档拒全占位/空行) |
| G5 | 输出规格表有非占位数据行(full 档拒全占位/空行) |
| G6 | 边界情况章节非空壳(full 档验实质内容) |
| G7 | 验收标准 Checklist 非空且非全占位(full 档拒全 TODO/xxx) |
| G8 | 错误处理表(功能/API)有非占位数据行;或组件 Spec 行为规格同时覆盖正常类 + 异常类流程(同义词语义识别,且两小节非空壳,仅写主路径/空壳判 FAIL) |
> 正确性层(v1.3.5 新增):闸门不只验"存在性",也验"正确性"——占位符识别(TODO/待定/xxx/[姓名] 等)+ 章节/表格/流程的"实质内容体积"下限,拦住"写了但没写真东西"的空壳 Spec。仅 full 档强制实质下限(lite 维持存在性即可,保留减负);硬闸 G1/G2/G7 的占位符识别两档都生效。
> 轻量档说明:当 Spec frontmatter 标 tier: lite 时,G3/G4/G5/G6 降级为建议项(ADV),
> 不计入硬闸门、不阻塞交付;仅 G1/G2/G7/G8 仍为硬闸门。小需求直接减负。
> CLI 亦可 python scripts/check_spec.py x.md --tier lite 强制覆盖文件的档位。
自动闸门(保存即校验 · 本版新增)
把"建议性门禁"升级为"保存即校验"——无需记得手跑 check_spec.py。
识别机制
所有模板/示例头部已加 YAML frontmatter,含 spec_type: 字段(feature/api/component/generic)。
闸门脚本仅对含该 frontmatter 的 .md 生效,普通文档不受影响。
方式一:后台监视(立即可用,无需 hook 框架)
WorkBuddy 当前无"文件保存钩子"机制,用监视器常驻即可。Windows 下走内核事件驱动
(ReadDirectoryChangesW,零第三方依赖),目录静止时进程阻塞于内核态、不轮询、零 CPU 占用;
非 Windows 退回轻量快照对比兜底。
# 监听某目录(默认当前目录),任意含 spec_type 的 .md 存盘自动跑闸门
python scripts/watch_gate.py --dir "你的Spec工作目录" --interval 2 --log watch_gate.log
--interval是去抖窗口(秒)(默认 2):合并连续保存的突发,非轮询间隔;目录静止时几乎零开销。- 仅监听
.md的创建/修改;非 Spec 文件不会触发。 - 结果打印到控制台,
--log可选落盘;Ctrl+C 停止。 - 跳过技能自身
scripts/目录,避免自触发噪声。
方式二:hook 入口(供支持 on-save 的钩子框架注册)
scripts/hook_gate.py 是钩子命令本体,接收一个文件路径参数:
python scripts/hook_gate.py <刚保存的.md> [--strict] [--quiet]
- 非 Spec → 静默放行(exit 0)。
- 是 Spec → 调
check_spec.py跑 G1–G8,打印 PASS/FAIL 摘要。 - 默认 warn-only(exit 0,绝不阻塞保存);
--strict时 Spec 且 FAIL 返回 exit 1(供支持"阻断式"钩子的环境使用)。
方式三:WorkBuddy 原生 on-save hook(待平台支持)
待 WorkBuddy 提供文件保存钩子配置后,按 references/hook-config.md 的样例注册即可,
命令即指向 hook_gate.py。该文档随平台能力更新。
与子代理协作
- 研究员: 搜集竞品规格、行业标准
- 文案师: 润色用户提示文案、错误消息
- 落地执行: 接收
approvedSpec 作为上下文,据其实现代码、编写测试;验收阶段回对照 Checklist
参考文档
- 详细模板说明:
assets/templates/README.md - 规格示例:
assets/examples/feature-example.md(已含 Non-Goals + frontmatter,可作标杆) - DoD 闸门脚本:
scripts/check_spec.py - 保存即校验:
scripts/hook_gate.py(钩子入口) /scripts/watch_gate.py(后台监视) - WorkBuddy 原生 on-save hook 样例(待平台支持):
references/hook-config.md - 机器可读契约头说明:见上方「机器可读契约头(agent_contract)」节
上游同步(fork 维护 · 低负担)
本技能是 spec-coding 的 fork,上游更新由 SkillHub 覆盖到 ~/.workbuddy/skills/spec-coding,
本技能本体不受其影响。但当上游发布新版本时,你想知道"上游改了什么、我的 fork 是否漏了修复",
用自带比对脚本即可一键看清差异:
# 默认比对 spec-coding-plus 与同级 spec-coding
python scripts/diff_upstream.py
# 写出 Markdown 报告 + 打印 MODIFIED 文件的完整 unified diff
python scripts/diff_upstream.py --report diff_report.md --full-diff
脚本将每个文件归入四类:
- IDENTICAL — 与上游一致,无需处理
- MODIFIED — 两边都有但内容不同,需人工核对(可能上游修了 bug,要把改动并入 fork)
- ONLY_IN_FORK — 本 fork 独有文件(如 scripts/check_spec.py、hook_gate.py、references/hook-config.md、generic-spec.md),上游更新绝不会覆盖,可放心保留
- ONLY_UPSTREAM — 上游独有/新增文件,提示你可酌情借鉴
> 铁律:脚本只读,绝不修改上游 spec-coding 本体。合并上游改动时务必手动把上游修复复制进 fork 对应文件,不要整包覆盖(否则会丢失本版的 Non-Goals 护栏、DoD 闸门、agent_contract 等改进)。
> 基线版本记录在 _meta.json 的 forkOf 字段(结构化 {slug, version, source, diffTool}),便于追溯。