| name | x-spec |
| description | 系统方案规划 skill。产出 docs/spec/<spec-name>/ 下的独立需求包(目标与 DoD + 组件设计 + 接口/数据结构 + 核心流程时序 + 验证策略 + task 映射)。
当用户给的是模糊想法而非具体功能需求时使用。触发场景:
"这个东西怎么设计"、"帮我梳理整体方案"、"先别写代码把方案理清"、
"这个系统该怎么拆"、"x-spec"、架构级改造、
一个系统切面会派生多个 task 需要先建 spec 需求包。上下文不足时先进入头脑风暴模式,收敛后再保存 spec 文档。
入口选择:小功能小修复由 x-req 定级 Q0/Q1;已有明确需求走 x-req。
|
x-spec 系统方案规划器
核心定位
x-spec 是方案型 skill,负责把一个模糊的系统想法整理成可导航、可拆分、可演进的方案文档体系。
x-spec 负责:
- 从第一性原理推导用户需求的本质:用户真正要改变的系统结果、关键约束、不可破坏的不变量
- 判断当前上下文是否满足 spec 立项所需目标;缺关键目标时进入头脑风暴模式
- 给出合理设计方案,并为每个关键判断写明判断依据、这样做的原因、缺失后的后果
- 产出系统级方案目录和总导航 README
- 拆分系统模块,定义模块职责、边界、依赖、状态
- 标记哪些模块已足够稳定,可以进入 x-req
- 建立 spec 需求包与 task 的映射关系
- 还不够稳的模块要在90-task-map.md进行记录,并写清楚需求还没确认,不能进入开发
绝对禁止:
- 需求目标不明确就糊弄过去
- 用户没同意就强行保存文档,除非用户说你全权负责
- 当前环境下过度设计
核心边界:
x-spec 输出系统组织方案;具体代码开发进入 x-req / x-dev。
第一性原理产物链路
事实 / 约束 / 不变量 / DoD
→ 必要能力集合
→ 模块划分
→ 边界类
→ task
→ 验证方式
适用场景
以下情况优先使用 x-spec:
- 用户给的是模糊想法或系统方向
- 涉及多个模块、多个阶段、多个 task
- 方案讨论比代码实现更重要
- 当前不确定该不该拆分
- 一个文档可能会非常长,需要拆成导航 + 子文档
- 需要先形成系统级共识,再进入开发
以下情况优先走其他入口:
- 小功能、小修复、单文件改动 → x-req 定级 Q0/Q1
- 已经有稳定需求报告(README.md),只差 dev-checklist/dev → x-req
- 用户明确要求立即开发一个清晰范围的功能 → x-req 定级后续接 x-dev
文档生成规则
模板是文档格式正源,skill 本体只负责判断、收敛、调度和审核。
- 先读
skills/x-spec/templates/TEMPLATE_GUIDE.md,再复制各模板写入 docs/spec/<spec-name>/
- 图表规范以
skills/x-spec/templates/TEMPLATE_GUIDE.md「图表规范」为准:图内嵌于其文字真源文件(不单设图集),默认只画 03-core-workflows.md 的核心时序,其余按需
- 路径引用规则以
skills/x-spec/templates/TEMPLATE_GUIDE.md 为准
- 每个关键结论都要回答:为什么重要、判断依据、缺失后的后果、落到哪个产物
原则
- spec 需求包是独立可传递的文档包:拿走
docs/spec/<spec-name>/ 给任何人,不依赖 dev-pipeline/tasks/
docs/spec/README.md 只做导航和 spec 状态汇总,不堆内容
- spec README 只做导航和目标概述,细节在子文档
- 子文档按编号排序,方便顺序阅读
路径引用规则(硬约束)
spec 需求包必须能整体移动。规则条文正源:templates/TEMPLATE_GUIDE.md「路径引用规则」;机器把关:python3 tools/xdev.py validate <包目录>(规则 V2)——本节不复读条文。速记:包内链接只用 ./...,代码路径只写 repo:<path> 纯文本。
状态定义(真源)
spec 与模块共用以下状态机;其它位置只引用本节,不再重复枚举取值。
- 探索中:边界未定,仍在收敛
- 方案确认:边界与 DoD 已定,尚未拆 task
- 可进入 x-req:可派生 task 进入 x-req
- 开发中:已派生的 task 正在实现
- 已完成:派生的 task 全部完成并验收
spec 状态反映整个需求包的进度;模块状态反映单个模块的进度;两者取值范围相同。
子 agent 使用边界(真源)
公理:子 agent 没有对话上下文(能力弱)。因此 x-spec 里子 agent 只有两个角色,共同形状:只读、只回带指针(文件+行号)的判定/证据清单、不生成产物内容——判定 + 指针一跳可核实(让谎言昂贵),而总结/扩写的忠实性要重读全文才能核对,核实成本 ≈ 自己写,必亏。
- 斥候(步骤 3,可选):调研现有代码,回收可复用清单
- 裁判(步骤 6.2):以 01 为公理审核产物,回收 P0/P1 判定清单
生成/总结/扩写类任务(写文档、压缩、改写)一律留在主窗口——生成需要用户意图,意图只在主窗口对话里。
工作流程
1. 上下文充分性判断
先判断当前上下文是否已经足够进入文档模式。判断结果写成临时工作记录,后续灌入 README.md 与 01-goals-and-boundaries.md。
| 必须目标 | 满足标准 |
|---|
| 需求本质 | 能说清用户真正要改变的系统结果 |
| 成功标准 | 能写出可验证 DoD、可观察证据、验收入口 |
| 范围边界 | 能区分包含、保留、延后、排除 |
| 关键约束 | 能列出技术、业务、时间、兼容性、权限、运维约束 |
| 系统不变量 | 能列出任何方案都必须保持成立的规则 |
| 现状依据 | 能找到代码、文档、配置、日志、用户描述中的证据 |
| 推荐方案 | 能给出方案、理由、代价、风险、失败场景 |
| 模块边界 | 能判断模块归属、边界类、依赖方向 |
| 数据和状态 | 能判断核心实体、状态归属、持久化策略 |
| 验证策略 | 能说明 smoke/e2e、单元、契约、边界测试的落点 |
| task 拆分 | 能判断哪些模块可进入 x-req、哪些仍停留在方案层 |
每个目标都要写清:
- 判断结论:已满足 / 待确认 / 缺失
- 判断依据:来自用户输入、现有代码、文档、配置、日志或明确推断
- 为什么重要:它会保护哪个系统结果或协作边界
- 缺失后果:继续写 spec 会产生的偏差、返工或风险
- 下一动作:进入文档模式 / 进入头脑风暴模式 / 向用户提问 / 先调研代码
2. 头脑风暴模式(上下文不足时)
任一 P0 目标缺失时先进入头脑风暴模式。该模式用于收敛 spec 输入,产物是对话中的决策记录和后续文档里的 Framing Summary。
必须完成:
- 第一性原理推导:把需求还原为目标、事实、约束、不变量、可重新评估的历史假设
- 需求本质:用一句话说明用户真正要达成的系统结果
- 方案空间:给出 2-3 个合理方向;每个方向写明适用条件、代价、风险、失败场景
- 推荐方案:说明当前证据最支持的方向,以及选择它的判断依据
- 后果说明:解释这样做保护了什么;继续缺失关键目标会导致什么后果
- 待确认问题:只问会改变 spec 方向的问题,每轮最多 8 个
可使用的判断原则:
- 第一性原理:从目标、事实、约束、不变量重新推导方案
- 奥卡姆剃刀:优先选择模块更少、状态更少、协议面更小、迁移成本更低的方案
- 贝叶斯判断:根据证据更新方案置信度,把不确定项转成调研或提问
- 对抗性检验:主动寻找会让方案失败的输入、状态、权限、并发、回滚、兼容性场景
- 可证伪性:关键判断必须能被代码、日志、测试、配置或用户确认验证
提问规则:
- 问题必须指向 spec 范围、验收标准、模块边界、数据归属、兼容性或方案选择
- 用户说“不要问了直接做”时,按已有信息产出,并在文档中标注待确认项
3. 现有资源调研(手里有什么牌)
上下文充分性判断完成后、拆模块前,LLM 主动调研(同时读取本地证据):
- 扫项目代码结构,找已有的可复用模块/函数
- 找已有的相似功能(避免重复造轮子)
- 找已用的第三方依赖(影响技术选型)
- 找已有的数据格式/存储(影响数据结构设计)
- 汇总"可复用清单"给用户确认
- 如果发现现有架构不满足新增当前需求功能,则必须提醒用户需要进行老模块优化
调研执行方式(二选一):
- 仓库小或主 agent 已熟悉(默认)→ 主 agent 直接扫
- 仓库大或不熟悉 → 派只读斥候子 agent(边界见「子 agent 使用边界」),任务书四件套:
- 带上需求本质——不说明"为了什么找",斥候不知道"可复用"对谁可复用
- 每条结论必须带
文件:行号 证据
- 显式允许负结果:"没找到可复用项"如实回报,禁止硬凑
- 只读禁改,只回结构化清单
斥候回报后,主 agent 抽查核实至少一条再采信。
如果是全新项目(无已有代码)→ 跳过本步,直接进拆模块。
4. 判断是否需要拆系统
满足任意两项,则建议拆模块:
- 涉及多个代码包或层
- 可独立测试的子能力超过 3 个
- 预期会拆成多个 task
- 单文档预计过长
- 模块之间依赖关系明显
- 用户自己也不确定边界
匹配度较低时,建议进入 x-req:小改动定级 Q0/Q1;单功能在同一入口完成澄清与拆解。
5. 拆分系统模块
模块来源规则
- 模块不能直接从技术名词、目录习惯或用户口头模块名生成。
- 每个模块必须由一个或多个必要能力聚合而来。
- 每个模块必须能追溯到 DoD、约束或不变量。
每个模块至少定义:
- 模块名称
- 职责
- 包含范围
- 不包含范围
- 依赖
- 边界类(模块唯一对外入口,命名见下方设计原则)
- 数据结构/接口(对外暴露的核心类型)
- 复用/新建标注(步骤 3 的调研结论)
- 风险等级(高/中/低)
- 当前状态
模块边界设计原则(硬性,开发类任务必须遵守)
- 每个模块对外只暴露一个边界类作为唯一入口:业务域用
<模块>Service、资源/生命周期域用 <模块>Manager、对接外部系统用 <系统>Client / <系统>Gateway、数据持久层用 <实体>Repository
- 模块内功能统一由边界类收口调用,禁止散装函数跨模块直接调用。判定标准:"改一个能力只动一处"——跨文件改多处就是边界没收口
- 模块内高内聚、模块间低耦合:模块外的代码只 import 边界类,grep 不到对模块内部函数的直接引用
- 文件级信号配合类名:Python 内部实现用下划线前缀文件/函数 +
__init__.py 只导出边界类(显式 __all__);TS 只从 index.ts 导出边界,内部实现放 internal/
内部功能需要对外暴露时(决策规则)
按序判断:
- 是本模块能力 → 边界类加委托方法(转发时顺手补校验,维持不变量),内部函数保持私有
- 是通用工具(与本模块业务无绑定)→ 提取到共享底层模块(
common/ / core/),双方都走它的边界
- 外部需要的内部能力多到边界形同虚设 → 模块边界画错了,回 x-spec 重新拆
禁止:直接 import 内部函数(如 from mod._internal import foo)/ 为一个调用方批量 re-export 内部文件 / 复制实现到调用方。
模块状态取值见「状态定义」。
6. 生成文档(主 agent 亲写全部 + 裁判审核)
强约束:spec 包内全部 7 个产物文件(README/01/02/03/04/05/90)由主 agent 亲自写。生成需要用户意图,而意图只在主窗口的对话里——扩写/总结类子 agent 没有对话基准,会产出"貌似合理的发明"且审核抓不住(见「子 agent 使用边界」)。
模板落点:DoD 追溯写入 01-goals-and-boundaries.md;风险标注写入 02-module-breakdown.md;PoC 和排序依据写入 90-task-map.md;具体写法以 templates/TEMPLATE_GUIDE.md 为准。
6.1 写作顺序(主 agent)
01 是存档点:长头脑风暴后窗口吃紧时,以落盘的 01 + 用户确认结论为基准续写,不依赖窗口内的对话副本。
01-goals-and-boundaries.md(模板 templates/01-goals-and-boundaries.md):
- 第一性原理推导 / 目标充分性判断(步骤 1-2 结论)
- 需求要点(步骤 1-2 对话提炼)
- 用户要求与证据表:逐条记录用户在追问中提出的原始要求,每条标注它在文档包里的落实位置(文件 + 段落/锚点)。裁判审核逐条核对,证据缺失 = P0
- 系统目标 / 成功证据 / DoD / 范围边界 / 关键约束 / 系统不变量
- DoD ↔ 模块追溯矩阵(TEMPLATE_GUIDE 的 DoD 追溯规则)
- 交用户确认前快速自查:追溯矩阵双向闭合、DoD 可验证不空话
03-core-workflows.md(核心流程):流程文字 + 时序图同文件(最小可用路径必写必画、含错误路径;最高风险链路与 E2E 验收链路可选)。跨模块的调用顺序/错误路径/异步边界只在这里显性化,它是设计判断的载体,随 01 一起交用户确认;总览/局部/状态/数据图默认不画,按需内嵌各自的文字真源文件(见 TEMPLATE_GUIDE「图表规范」)
- 用户确认(第一级审核;基准 = 用户意图,只有用户持有):
- 需求要点是否忠于用户原意
- 范围边界 / "不包含"是否对
- MVP 链路选得对不对——对着核心时序图确认
- 用户有异议 → 主 agent 改 01/图后重新确认;要求的改动数计入 run 记录
user_edits
02-module-breakdown.md(组件设计 + 接口 + 数据结构 + 风险标注——设计判断,不外包)
04-data-and-state.md(核心数据模型 + 状态流转)
05-validation-and-evolution.md(验证策略 + 测试 + 演进)
90-task-map.md(组件→task 映射,依据 01 追溯矩阵 + PoC 排序)
<spec>/README.md(最小可用路径、模块导航、当前建议)+ docs/spec/README.md 索引
6.2 裁判审核(子 agent,一次性、只读)
7 文件全部落盘后,主 agent 先跑 python3 tools/xdev.py validate <spec目录>——机械项(文件齐全 / 路径规则 / Requirement-Scenario 结构 / 02↔90 清单一致 / 状态取值)由工具零成本把关,validate 零 finding 后才派裁判,机械项不占裁判窗口;validate 的 finding 编号(V1-V7)可写进 run 记录聚合。
然后派裁判。裁判没有对话上下文——这不是缺陷是特性:写作者自审只能看到"想写的",fresh eyes 才看得到"实际写的"。基准已外化且经用户确认(01),裁判拿 01 当公理审下游。
禁止让裁判审 01 对用户意图的忠实性——那一层基准只有用户持有,已在 6.1 第 3 步完成。
Agent({
description: "x-spec 裁判审核",
subagent_type: "general-purpose",
prompt: <短任务书,不塞文档全文(基准与产物都在盘上,裁判自己 Read):
- 审核目录 docs/spec/<spec-name>/,以其中 01-goals-and-boundaries.md 为公理基准
- 只读禁改:不允许修改任何文件
- 按规则 R1-R8 逐条审核(规则全文贴入),每条 finding 必须带 文件+行号/锚点 证据
- 显式允许负结果:某规则查无问题就写"未发现",禁止硬凑 finding
- 输出只准是按回报模板的判定清单,禁止复述或总结文档内容>
})
审核规则(finding 按编号回报,编号进 run 记录聚合):
| # | 规则 | 等级 |
|---|
| R1 | 忠于 01:02/03/04/05/90 的模块、组件、数据结构不与 01 的需求要点、模块拆分冲突 | P0 |
| R2 | 追溯闭合:每条 DoD 有模块支撑、每个实现模块回指 DoD;每个模块可追溯到 DoD、约束或不变量 | P0 |
| R3 | 证据表落实:01 用户要求与证据表每条指到的位置真的落实了该要求 | P0 |
| R4 | task 来源闭合:每个 task 回指模块 + DoD;不稳模块记录在 90 且标"需求未确认,不能进入开发" | P0 |
| R5 | 判断依据完整:推荐方案、模块边界、数据归属、验证策略写明为什么重要、判断依据、缺失后果 | P0 |
| R6 | 文档间一致:02 模块清单 / 03 时序图中的模块与边界类名 / 90 映射对得上;每个模块定义了边界类 | P0 |
| R7 | 机械项已由 tools/xdev.py validate(V1-V7)前置把关,裁判不重查;仅当 validate 输出未附或有未修 finding 时记 P0。图内嵌于文字真源、无孤立图集仍由裁判目检 | P0 |
| R8 | 数据结构字段中文注释、图表格式、task 排序依据强度 | P1 |
裁判回报模板:
## Judge Report
**Status:** done / blocked
| # | 判定 | 证据(文件 + 位置) |
|---|------|---------------------|
| R1 | 未发现 / P0:<一句话> | `02-module-breakdown.md#模块-a` |
6.3 修复(主 agent 直接改)
- 主 agent 对裁判清单先抽查核实至少一条——finding 也不是地面真值,指针指到的原文才是;核实不成立的驳回,计入 run 记录
judge_fp
- 成立的 P0 主 agent 直接 Edit 修复(基准与文件都在主窗口,成本最低,无重派分支);P1 顺手修掉,避免永久遗留
- 修复后重跑
python3 tools/xdev.py validate(机械项复查,零成本),不重派裁判
- 无 P0 → 直接进步骤 7(剩余 P1 列给用户参考,不阻塞)
spec README 必须包含:
- spec 目标
- 最小可用路径(MVP 链路,一句话描述核心路径)
- 组件导航 + 状态表
- 文档导航
- 当前建议
spec 索引 README 必须包含:
- spec 族职责(一句话)
- spec 导航表(名称 + 状态 + 说明)
7. 给出下一步建议
必须给出明确结论:
- 哪些模块继续留在方案层
- 哪些模块可以进入 x-req
- 高风险模块是否建议先 PoC
- 是否建议现在就拆 task
模板文件
所有模板在 skills/x-spec/templates/ 下,LLM 产出时复制对应模板并填充内容:
| 模板文件 | 对应产出 | 层级 |
|---|
templates/TEMPLATE_GUIDE.md | 模板说明:字段、路径、图表、审核规则 | skill 内部参考 |
templates/module-README.md | spec 索引导航 | docs/spec/README.md |
templates/README.md | spec 导航 | docs/spec/<spec-name>/README.md |
templates/01-goals-and-boundaries.md | 目标 + 完成标准 + 范围 + 用户要求与证据 | spec 目录 |
templates/02-module-breakdown.md | 组件设计 + 接口 + 数据结构 | spec 目录 |
templates/03-core-workflows.md | 核心流程文字 + 时序图(E2E 验收链路可选) | spec 目录 |
templates/04-data-and-state.md | 核心数据模型 + 状态流转 | spec 目录 |
templates/05-validation-and-evolution.md | 验证策略 + 测试 + 演进 | spec 目录 |
templates/90-task-map.md | 组件→task 映射 | spec 目录 |
输出要求
完成后,必须向用户明确说明:
- 该模块是否还需要拆更多 spec
- 当前 spec 的状态(取值见「状态定义」)
- 哪些 spec 适合先进入 x-req
- 哪些 spec 仍应停留在方案层
- 文档保存路径:
docs/spec/<spec-name>/
- 审核结论:裁判 6.2 发现的 P0(已修复 / 驳回误报分别注明)+ 遗留 P1(参考项,不阻塞)
- run 记录已追加至
docs/spec/run-log.jsonl(字段与退场判据见「run 记录与退场判据」)
如果用户仍然很模糊,优先产出最小 3 文件,其余文档标为后续扩展。
run 记录与退场判据(埋秤)
每次 x-spec 运行结束(步骤 7 完成后),向 docs/spec/run-log.jsonl 追加一行(append-only;仅 late_findings 事后发现时允许回补对应行):
{"ts":"YYYY-MM-DD","spec":"<spec-name>","mode":"new|update","duration_min":38,"confirm_rounds":2,"user_edits":3,"judge_p0":["R2@02:45 追溯缺口"],"judge_p1":[],"judge_fp":1,"late_findings":0,"repairs":[{"item":"R2","by":"main"}],"notes":"一句话"}
字段只收观察得到的,不收测不准的(如 token 数):
confirm_rounds:用户确认往返数(6.1 第 3 步)
user_edits:用户确认环节要求的改动数——主 agent 一版质量信号
judge_p0 / judge_p1:裁判 finding,按规则编号——模板进化数据
judge_fp:主 agent 核实后驳回数——裁判质量信号
late_findings:裁判放行后用户或下游又发现的问题数——裁判漏报信号
预注册退场判据——看到什么就做什么,防止度量退化成仪式:
| 信号 | 动作 |
|---|
user_edits 持续 ≥3 | 病在 01 之前的收敛环节 → 改步骤 1-2(充分性判断/头脑风暴),不是加审核 |
| 某规则 10 次运行 0 触发 | 从裁判 rubric 删掉这条规则——没人犯的规则也在付装配税 |
| 某规则高频触发 | 改上游(模板 / 主 agent 写作指令),不是让裁判反复兜 |
| 裁判连续 5 次 findings 全空或全误报 | 裁判退场:删 6.2,机械项(R7)并回主 agent 自查 |
late_findings 持续 > 裁判抓到数 | 裁判 rubric 失焦 → 重写 rubric |
目录结构
spec 需求包模型
spec 采用 docs/spec/<spec-name>/ 独立需求包目录:
- docs/spec/:所有 x-spec 需求包的固定根目录
- spec-name:一个系统切面/主题,每次 x-spec 运行聚焦一个 spec 需求包
多个 spec 组合成完整系统方案(如 scheduler-cron-parsing + scheduler-task-dispatch + scheduler-retry-backoff 三个 spec 组成 scheduler 方案族),同一个 spec 迭代时原地更新(不另起目录)。
确定输出目录
- 用户指定或 agent 推断出
<spec-name>,使用 URL 友好命名(空格转 -,斜杠转 -)
- 检查
docs/spec/ 是否存在:
- 不存在 → 创建
docs/spec/ + docs/spec/README.md + spec 需求包目录 + spec 7 文件
- 已存在 → 检查
docs/spec/<spec-name>/:
- spec 不存在 → 创建 spec 需求包目录 + 7 文件,更新
docs/spec/README.md 索引
- spec 已存在 → 增量更新已有文件(原地迭代),更新前告知用户将改动哪些文件
目录结构
docs/spec/
├── README.md # spec 索引(汇总所有 spec 状态)
├── <spec-name>/
│ ├── README.md # spec 导航 + 目标
│ ├── 01-goals-and-boundaries.md # 目标 + 完成标准 + 范围 + 用户要求与证据
│ ├── 02-module-breakdown.md # 组件设计 + 接口 + 数据结构
│ ├── 03-core-workflows.md # 核心流程:文字 + 时序图(跨模块协作唯一载体)
│ ├── 04-data-and-state.md # 核心数据模型 + 状态流转
│ ├── 05-validation-and-evolution.md # 验证策略 + 测试 + 演进
│ └── 90-task-map.md # 组件→task 映射
├── <other-spec>/
│ └── ...(同上 7 文件)
legacy 兼容:旧 spec 包里已有的 diagrams.md 原地迭代时保留、不强制迁移;新 spec 不再生成独立图集文件,图内嵌于其文字真源文件。
spec 索引 README
spec 索引 README(docs/spec/README.md)只做导航和状态汇总,模板见 templates/module-README.md(保留旧文件名兼容)。每次新增/更新 spec 时同步更新。