Spec 起草助手 (Spec Drafter)
版本: 2.0.0 | 十步循环: A.1 Spec管理 架构: 双层任务架构 (tasks.md + detailed-tasks.yaml)
快速开始
我应该使用这个 Skill 吗?
使用场景:
- A.1: 为新功能/变更创建 OpenSpec 规范
- 需要自动判断 Spec 级别 (Level 1/2/3)
- 需要生成符合模板的 proposal.md
- 需要拆解大功能为 tasks.md
不使用场景:
- 简单的 typo/格式修复 → Level 1,直接跳过 A.1
- 查询项目状态 → 使用
state-scanner(A.0) - 规划任务执行 → 使用
task-planner(A.2)
核心功能
| 功能 | 描述 |
|---|---|
| Level 自动判断 | 根据需求内容判断 Spec 级别 (1/2/3) |
| 信息提取 | 从用户输入提取 Why/What/Tasks 等信息 |
| 模板生成 | 生成符合 OpenSpec 规范的 proposal.md |
| Level 3 扩展 | 架构变更时额外生成 tasks.md |
| 交互模式 | 逐章节确认和修改 |
| 上下文增强 | 集成 state-scanner 获取项目状态 |
| 头脑风暴集成 | 内置 brainstorm 流程,基于决策记录预填充 |
三级 Spec 策略
| Level | 名称 | 触发条件 | 产出物 |
|---|---|---|---|
| 1 | Skip | 简单修复、配置、格式 | 无 Spec |
| 2 | Minimal | 中等功能 (1-3 天) | proposal.md |
| 3 | Full | 架构变更、跨模块 | proposal.md + tasks.md |
详细判断规则: LEVEL_GUIDE.md
输入参数
| 参数 | 必需 | 说明 | 示例 |
|---|---|---|---|
requirement |
✅ | 需求描述 | "创建用户认证功能" |
module |
❌ | 目标模块 (自动检测) | mobile, backend, standards |
interactive |
❌ | 是否交互模式 (默认 true) |
true, false |
create_file |
❌ | 是否直接创建文件 (默认 false) |
true, false |
level_override |
❌ | 强制指定 Level | 1, 2, 3 |
前置: REQUIRE claim (A.1, MUST)
起草之前先认领, 不可跳过。
幂等分工: 正常委派路径 (phase-a-planner → 本 skill) 下认领已在上游做过, 本块只在
(a) 未经 phase-a-planner 直接调用本 skill, 或 (b) phase-a-planner 因 skip 条件
未走到认领 —— 这两种情况下生效。下面的幂等 check 就是用来分辨的; 直调路径没有 Level 判定,
因此本块无 Level 1 例外。
python3 "${CLAUDE_PLUGIN_ROOT:-aria}/skills/state-scanner/scripts/phase1_gate.py" \
--raw-track-id "<spec-slug>-<container_uuid>" \
--phase A.1 --mode advisory \
--linked-issue "<org>/<repo>#<n>" \
--include-terminal \
--repo-path "<主仓根>"
为什么在这里: 十步循环的 10 轮闸门, 没有任何一条问过「远端是不是已经有人在做同一件事」。 它们审的都是这份产物做得对不对, 从不问它该不该存在 —— 已经有 5 次两个容器对同一个 issue 各自起草、各跑数轮审计、互不知情, 直到一方 ship 才发现。认领必须早于投入, 否则它记录的 只是既成事实。
实参怎么来:
--raw-track-id: 逐字拼<spec-slug>-<container_uuid>—— slug = 本 Spec 目录名openspec/changes/<slug>/逐字(不预归一, 归一在 CLI 内部做); uuid 段取~/.aria/container-id的uuid字段, 不是label—— 改一行装饰性 label 不该换掉 track-id。--linked-issue: 两阶段取法。若${CLAUDE_PLUGIN_ROOT:-aria}/skills/state-scanner/scripts/linked_issue_field_probe.py存在, 实参 =python3 <该脚本> --emit-arg <本 Spec 的 proposal.md>的 stdout(输出为空 ⇒ 整个参数省略); 否则按字段 Spec E6 手工判 —— 只有字段行冒号后首个 code span 的第一个元素形如<org>/<repo>#<n>且非哨兵时才传。哨兵 /BAD_TOKEN/NO_TOKEN/NO_FIELD一律省略整个参数, 绝不可把哨兵当值传: 任何非空字符串都 truthy, 两份毫无关系的 Spec 只要都写哨兵就会互相命中。
幂等 —— 已经认领过就不要再认领一次:
check: coordination ref 内按 (container_id, session_id) 定位到本 session 的 active claim
(claims/<container>/<session>.yaml 存在且 status == active)
if_missing: 跑上面的命令; 已存在则跳过, 不重复 acquire
输出怎么读 (四态, 两两不同):
| 信号 | 含义 | 措辞 |
|---|---|---|
| 键缺席 | 未检测(没传 --linked-issue) |
「本轮未检测」 |
linked_issue_overlap == [] |
已检测, 无碰撞 | 「无碰撞」 |
unknown_schema_claims > 0 |
有 N 条读不懂 schema 的 claim | 「已检测到 N 条无法解析的 claim —— 存在性已确认、内容未知, 按存在处理」 |
linked_issue_overlap == null 且 linked_issue_overlap_error 非空 |
本轮没取到任何证据 | 「未能核实, 建议重试」 |
⚠️ 最后一行绝不可渲染成「无碰撞」—— 零证据不是正证据。同理不要用 .get(key, []) / .get(key, 0)
去读这几个键, 那正好把四态压成一态。
退出义务 (两条, 缺一就留下永不释放的僵尸 claim):
改名 ⇒ release 旧 + acquire 新—— Spec 目录改名就是换了 track-id, 必须两步走。放弃方向 ⇒ release_gate.py --raw-track-id <同一串> --status abandoned
overlap 非空时按对方 claim 的 status 分档请裁(经 AskUserQuestion, 不自行放行):
告警须含五要素 —— 对方 track_id / owner-container / claimed_at / 双方 linked_issue 原始串 / status。
linked_issue 要逐字回显原串(如 10CG/Aria#174, 不要缩成 #174), claimed_at 也不要截断成日期 ——
org 段不参与匹配, 回显原串是人工判别「误配」的唯一手段; 缩写与截断正好把这个手段消掉。
| 对方 status | 处置 |
|---|---|
active |
有人正在做 —— 请裁: 合并方向 / 换方向 / 确认确实是两件事 |
unknown |
读不懂其 schema, 视同 active 处理(存在性已确认) |
done / abandoned |
同一件事可能已经做完或已被放弃。按 active 同档请裁, 并注明该终态也可能是 GC 产物而非真的做完。不要提议去释放对方的 claim —— 那是对方的东西 |
执行流程
A.1.0 - 头脑风暴检查 (新增):
- 检查是否有现有决策记录 (docs/decisions/)
- 根据文档类型决定是否需要头脑风暴:
* 创建 PRD: 检查是否有 problem decision-log
* 创建 OpenSpec: 检查是否有 technical decision-log
- 如无决策记录,询问是否先运行 brainstorm
A.1.1 - 收集需求信息:
- 从决策记录预填充 (如有)
- 提取需求标题 (Feature Name)
- 提取动机说明 (Why)
- 提取功能描述 (What)
- 提取交付物列表 (Deliverables)
- 提取约束条件 (Constraints)
- 框架约定 (Framework Constraints, Aria #95, 可选): framework 项目 (Next.js /
Astro / SvelteKit / Vue / Remix 等) 在 proposal 加一段已知 framework
convention / anti-pattern (route handler export 限制 / private-folder
routing / use client·server / metadata 白名单), 供 post_spec/post_impl
审计 agent 直接对照 (见 agent-team-audit/references/audit-points.md
「横切检查原则 · 框架约定」)。无 framework 项目跳过。
A.1.2 - Level 判断:
- 关键词匹配 (Level 1/3 触发词)
- 文件影响范围分析 (跨模块检测)
- 变更类型识别 (breaking change)
→ 详见 [LEVEL_GUIDE.md](./LEVEL_GUIDE.md)
A.1.3 - 模块检测:
- mobile: Flutter/Dart, UI组件, 移动端
- backend: Python, API, FastAPI, 数据库
- shared: 契约, Schema, OpenAPI
- standards: 规范, Skill, OpenSpec
A.1.4 - 生成 Spec 文档:
Level 2: openspec/changes/{feature}/proposal.md # 本项目仓内, 不是 standards/
Level 3: proposal.md + tasks.md (OpenSpec 双层架构格式)
⚠️ 路径落点 = **消费方项目自己的** `openspec/changes/`。standards 是共享子模块,
把项目变更写进 `standards/openspec/changes/` 会让该变更对所有采用方可见且无人拥有
(Aria 不可协商规则 #5)。standards 自身的规范变更才落 standards 仓。
- 预填充决策引用 (如有决策记录)
- 头部 Linked Issue 字段 (必填): 见下方「proposal.md 头部字段要求」
A.1.5 - 交互确认 (可选):
逐章节确认: Level → Why → What → Deliverables → Impact → Tasks → Success Criteria
A.1.6 - 验证提示:
输出: "建议运行 openspec validate {feature} --strict 验证格式"
输出格式
Level 2 预览
╔══════════════════════════════════════════════════════════╗
║ SPEC DRAFT PREVIEW (Level 2) ║
╚══════════════════════════════════════════════════════════╝
Feature: user-authentication
Module: backend
Location: openspec/changes/user-authentication/proposal.md
──────────────────────────────────────────────────────────
# User Authentication
> **Level**: Minimal (Level 2 Spec)
> **Status**: Draft
> **Created**: {YYYY-MM-DD}
> **Linked Issue**: `{<org>/<repo>#<n>}`
## Why
为应用添加用户身份验证功能,保护敏感操作和数据。
## What
实现基于 JWT 的用户认证系统。
### Key Deliverables
- backend/src/services/auth_service.py
- backend/src/routes/auth_routes.py
## Tasks
- [ ] 设计用户数据模型
- [ ] 实现 JWT 认证服务
## Success Criteria
- [ ] 用户可注册和登录
- [ ] 测试覆盖率 >= 85%
──────────────────────────────────────────────────────────
🤔 Create this file? [Yes/No/Edit]
Level 3 预览
╔══════════════════════════════════════════════════════════╗
║ SPEC DRAFT PREVIEW (Level 3 - Full) ║
╚══════════════════════════════════════════════════════════╝
Feature: progress-management-refactor
Module: cross (standards + mobile + backend)
📄 Files to Generate:
├── proposal.md - 功能规范
└── tasks.md - 任务分解 (OpenSpec 双层架构)
🤔 Create these files? [Yes/No/Edit]
Level 1 输出
═══════════════════════════════════════════════════════════
LEVEL 1 DETECTED - SKIP SPEC
═══════════════════════════════════════════════════════════
此需求为简单修复,建议直接跳过 A.1:
- 类型: 文档格式/Typo 修复
- 影响: 单文件
- 风险: 极低
📋 推荐操作:
直接进入 B.1 (分支创建) 开始开发
上下文增强
当指定 module 时,自动从 state-scanner 获取上下文:
获取信息:
- 当前 Phase/Cycle
- 活跃风险列表
- KPI 快照
填充到 Spec:
- Impact.Risk: 关联现有风险
- Success Criteria: 参考 KPI 目标
详细示例: LEVEL_GUIDE.md
头脑风暴集成
集成概述
spec-drafter 与 brainstorm skill 深度集成,实现"决策优先于文档"的理念。
流程:
1. 检测决策记录
├── 有 decision-log → 预填充 Spec
└── 无 decision-log → 询问是否先头脑风暴
2. 预填充逻辑
├── Background ← problem 模式决策
├── Constraints ← 收集的约束条件
├── Technical Approach ← technical 模式决策
└── Decisions ← 引用决策 ID
3. 决策引用
├── 格式: [DEC-001](../../docs/decisions/problem-001.md)
├── 自动生成决策链接
└── 保持可追溯性
PRD 创建集成
触发场景: 用户要创建 PRD 文档
检查流程:
1. 扫描 docs/decisions/problem-*.md
2. 检查是否有相关决策记录
如有相关决策:
- 基于决策内容预填充 PRD
- 引用决策 ID
如无相关决策:
- 提示: "建议先运行 brainstorm.problem 澄清问题"
- 选项:
[1] 先头脑风暴 (推荐)
[2] 直接创建 PRD
[3] 取消
OpenSpec 创建集成
触发场景: 用户要创建 OpenSpec proposal
检查流程:
1. 扫描 docs/decisions/technical-*.md
2. 检查是否有相关技术决策
如有相关决策:
- 预填充技术方案
- 引用决策 ID
- 自动填充约束条件
如无相关决策:
- 提示: "建议先运行 brainstorm.technical 讨论技术方案"
- 选项:
[1] 先头脑风暴 (推荐)
[2] 直接创建 OpenSpec
[3] 取消
预填充格式
proposal.md 中引用决策的格式:
# {Feature Name}
> **决策来源**: [DEC-001](../../docs/decisions/problem-001.md), [DEC-002](../../docs/decisions/technical-001.md)
## 背景
> 基于 [DEC-001](../../docs/decisions/problem-001.md) 的讨论
用户需要 24/7 可用的客服支持...
## 约束条件
| 类型 | 约束 | 来源 |
|------|------|------|
| business | 预算 < $500/月 | DEC-001 |
| technical | 私有化部署 | DEC-001 |
## 技术方案
> 基于 [DEC-002](../../docs/decisions/technical-001.md) 的决策
采用自建 RAG 方案 (FAISS + 本地模型)...
## 关键决策
| 决策 | 选择 | 理由 |
|------|------|------|
| 向量存储 | FAISS | 满足成本约束 |
| 嵌入模型 | 待定 | 需要 brainstorm.technical 讨论 |
决策追溯链
决策链:
problem-001 (问题定义)
↓ 引用
requirements-001 (需求分解)
↓ 引用
technical-001 (技术方案)
↓ 引用
proposal.md (最终规范)
追溯:
proposal.md → technical-001 → requirements-001 → problem-001
完整的"为什么"决策链
proposal.md 头部字段要求
Level 2 / Level 3 的 proposal.md 头部 blockquote 必须含一行 Linked Issue 字段。字段顺序建议与 SOT 模板 proposal-minimal 模板 一致 (Level → Status → Created → Linked Issue) —— 从模板起草时自然满足, 无需额外对齐动作:
> **Linked Issue**: `<org>/<repo>#<n>`
写法三条 (机械 check 按 Aria Spec linked-issue-field-availability §3 抽取规则 E0–E6 校验, 实现者零裁量):
- 值是 inline code span 形
`<org>/<repo>#<n>`(例`10CG/Aria#174`); 多个 issue 写在同一个 code span 内, 用,分隔 (例`10CG/a#1, 10CG/b#2`)。 - 无关联 (已核实) 时逐字写
`none`—— 不留空、不删行 (空值与「忘了写」不可区分);N/A/TBD/-不是哨兵, 会被判不合规。 - 行首无空白,
>后恰一个空格, 字段名两侧各两个星号, ASCII 冒号; 不写 markdown 链接形 ([repo#n](url)判NO_TOKEN)。读取侧另认中文 alias关联 Issue/无, 但新写一律用英文 canonical。
位置不影响机械判定 (裁定 2026-09-01 B8): check 按 E0 取文档序第一条 depth-1 命中, 不限行号 —— 既有 proposal 把字段写在超长头部 blockquote 的第 45 / 61 行仍判合规。「只扫头部 N 行」这个看起来更严的加固已被真实语料实测否决 (它会误杀两份真命中)。所以上面那条「顺序建议」是起草侧的模板对齐建议, 不是 check 的判据 —— 别为了「对齐」去改动既有 proposal 的头部顺序。
tasks.md 格式要求
Level 3 生成的 tasks.md 遵循 OpenSpec 双层架构:
格式要求:
- 使用 checkbox: - [ ] {Phase}.{Task} {Description}
- 编号格式: 1.1, 1.2, 2.1 (Phase.Task)
- 粗粒度: 功能层面,避免技术细节
- 编号不可变: 一旦创建不能修改
不包含:
- Agent 分配 (A.3 负责)
- 时间估算 (A.2 负责)
- 文件路径 (A.2 负责)
错误处理
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 无法判断 Level | 需求描述过于模糊 | 提供更详细描述,或使用 level_override |
| 模块检测失败 | 需求未涉及具体模块 | 手动指定 module 参数 |
| 信息提取不完整 | 需求缺少关键信息 | 使用交互模式逐项补充 |
| 文件已存在 | 同名 Spec 已存在 | 检查现有 Spec,考虑更新而非新建 |
与其他 Skills 的协作
state-scanner (A.0) ──▶ 状态感知
│
├── brainstorm (A.0.5) ──▶ 决策记录 ← 新增
│ │
└──────────────────────────────┘
▼
spec-drafter (A.1) ──▶ proposal.md + tasks.md (基于决策预填充)
│
▼
task-planner (A.2/A.3) ──▶ detailed-tasks.yaml
│
▼
branch-manager (B.1) ──▶ 功能分支
头脑风暴集成点
A.0.5 头脑风暴 (可选):
├── brainstorm.problem: 问题空间探索
├── brainstorm.requirements: 需求分解
└── brainstorm.technical: 技术方案设计
A.1 Spec 创建:
├── 检测决策记录
├── 预填充 Spec 内容
└── 引用决策 ID
决策记录 → Spec 同步:
docs/decisions/*.md → openspec/changes/*/proposal.md
检查清单
使用前
- 确认需求描述清晰完整
- 了解涉及的模块范围
使用后
- 已生成 proposal.md (Level 2/3)
- 已生成 tasks.md (Level 3)
- Level 判断合理
- 运行
openspec validate <feature> --strict验证格式 - 准备进入 A.2 任务规划
提示: 生成文件后建议运行
openspec validate <feature> --strict确保符合规范
子文件
- LEVEL_GUIDE.md - Spec Level 决策指南
相关文档
- 十步循环概览
- Phase A: 规范与规划
- OpenSpec 项目定义
- proposal-minimal 模板
- brainstorm - 头脑风暴引擎 (新增集成)
- state-scanner
- task-planner
最后更新: 2026-06-19 (Aria #95: A.1.1 加可选 Framework Constraints 提取) Skill版本: 2.2.0 (Framework Constraints 提取) 架构: 双层任务架构 (v2.0.0)