票务工艺技能
编写软件票务,AI代理可以自动执行。
**目的:**定义一个票务格式,结合软件工程最佳实践(INVEST,Given-When-Then,准备就绪的定义)与Claude Code特定上下文要求。使用此技能创建的每个票务都是"Claude Code就绪" - 意味着代理可以接手并执行它,而无需提出澄清问题。
**适用于:**Jira,Asana,Linear,GitHub问题,或任何票务系统。
核心原则
┌─────────────────────────────────────────────────────────────────┐
│ 一个票务是一个提示 │
│ ────────────────────────────────────────────────────────── │
│ │
│ 传统票务是为人类编写的,他们可以: │
│ - 在Slack上提出澄清问题 │
│ - 借助于机构知识 │
│ - 从模糊的描述中推断意图 │
│ │
│ AI代理无法做到这些。 │
│ │
│ 每个票务必须是自包含的: │
│ - 明确的文件引用(而不是“认证模块”) │
│ - 模式引用(而不是“遵循我们的约定”) │
│ - 验证标准(而不是“确保它有效”) │
│ - 约束(不仅仅是做什么,而是不做什么) │
│ - 测试命令(而不是“运行测试”) │
│ │
│ 如果Claude Code能够不问问题就执行它, │
│ 那么票务就准备好了。如果它不能,那么它就没准备好。 │
└─────────────────────────────────────────────────────────────────┘
INVEST+C标准
标准INVEST加上C为Claude就绪:
| 标准 | 问题 | 如果失败… |
|---|---|---|
| I - 独立的 | 这个可以不等待另一个票务就完成吗? | 被未记录的依赖关系阻塞 |
| N - 可协商的 | 是否有调整实施方法的空间? | 过度指定实现细节 |
| V - 有价值的 | 你能明确谁受益以及如何受益吗? | 没有明确的用户或商业价值 |
| E - 可估计的 | 团队是否足够了解以估算它? | 太模糊或太大而无法估计 |
| S - 小的 | 一个人能在1-3天内完成这个吗? | 超过5个验收标准 |
| T - 可测试的 | 你能为它编写一个通过/失败测试吗? | 使用模糊的语言,如“快速”或“良好的用户体验” |
| C - Claude就绪 | AI代理能否不提出澄清问题就执行这个? | 缺少文件引用,模式,验证或约束 |
票务类型
1. 功能票务
## [PROJ-XXX] {动词} {功能} 为 {用户}
**类型:** 功能
**优先级:** {关键 | 高 | 中 | 低}
**点数:** {1 | 2 | 3 | 5 | 8}
**标签:** {前端,后端,API,数据库等}
**史诗:** {父史诗}
---
### 用户故事
作为 {特定人物},
我想要 {特定行动},
以便 {可衡量的好处}。
### 背景
{1-2段关于为什么这很重要。链接到产品简介,用户研究,
或商业理由。包括任何相关的指标或用户反馈。}
### 验收标准
**AC1: {快乐路径场景}**
假设 {前提条件},
当 {行动},
那么 {预期结果}。
**AC2: {边缘情况/错误场景}**
假设 {前提条件},
当 {行动},
那么 {预期结果}。
**AC3: {边界条件}**
假设 {前提条件},
当 {行动},
那么 {预期结果}。
### 范围外
- {明确说明这个票务不包括什么}
- {防止范围蔓延,保持票务小}
---
### Claude Code上下文
#### 相关文件(首先阅读这些)
- `src/services/example.ts` - 要扩展的现有服务
- `src/models/example.ts` - 数据模型定义
- `src/api/routes/example.ts` - 要遵循的现有端点模式
#### 模式参考
按照 `src/services/user.ts` 中的模式进行服务层实现。
按照 `src/api/routes/users.ts` 中的模式进行路由定义。
按照 `tests/services/user.test.ts` 中的模式进行测试结构。
#### 数据库更改
- {要创建/修改的表,列,类型}
- {迁移文件位置:`supabase/migrations/` 或 `prisma/migrations/`}
- {如果使用Supabase,则为RLS策略}
#### API合同
POST /api/{资源} 请求:{ field1: string, field2: number } 响应:{ id: string, field1: string, created_at: string } 错误:{ error: string, code: number }
#### 约束
- 不要修改 {特定文件或模块}
- 未经批准不要添加新依赖
- 遵循 `src/core/exceptions.ts` 中的现有错误处理
- {任何性能预算:响应时间 < 200ms,捆绑包大小 < 50KB}
#### 验证
```bash
# 运行特定测试
npm test -- --grep "{功能名称}"
# 检查
npm run lint
# 类型检查
npm run typecheck
# 全验证
npm test -- --coverage
环境变量
- 现有:{在.env中已经相关的列表变量}
- 新增所需:{需要的新变量列表}
依赖关系
- 被阻塞:{PROJ-XXX} ({简短描述})
- 阻塞:{PROJ-YYY} ({简短描述})
设计
- 模拟:{如果适用,链接到Figma/设计}
---
### 2. 错误票务
```markdown
## [BUG-XXX] 修复:{组件} - {症状}
**类型:** 错误
**优先级:** {关键 | 高 | 中 | 低}
**点数:** {1 | 2 | 3 | 5}
**标签:** {回归,ux-bug,data-bug,security-bug}
**严重性:** {阻止用户 | 降低体验}
---
### 错误摘要
{一句话:什么坏了,谁受影响。}
### 环境
- 浏览器/操作系统:{例如,Chrome 120 / macOS 14.2}
- 环境:{生产 | 暂存 | 本地}
- 用户类型:{匿名 | 认证 | 管理员}
- 第一次观察到:{日期}
### 重现步骤
1. {导航到 / 执行操作}
2. {执行下一个操作}
3. {执行下一个操作}
4. **观察:** {错误行为}
### 预期行为
{应该发生什么。}
### 实际行为
{实际发生了什么。包括错误消息,控制台输出,屏幕截图。}
### 影响
- 用户受影响:{百分比或计数}
- 频率:{每次 | 间歇性 | 特定条件}
- 替代方案:{存在 / 无}
---
### Claude Code上下文
#### 疑似根本原因
{如果已知,错误可能存在的位置。}
- 文件:`src/components/LoginForm.tsx:87`
- 问题:`isSubmitting`状态在验证错误时设置为`true`但从未重置
#### 相关文件
- `src/components/LoginForm.tsx` - 有错误的表单组件
- `tests/components/LoginForm.test.tsx` - 现有测试(这里的差距)
- `src/hooks/useAuth.ts` - 表单使用的认证钩子
#### 测试差距分析
- 现有测试覆盖:{当前测试的内容}
- 缺少测试:{什么测试会捕获这个错误}
#### 错误修复工作流程(TDD)
1. 编写一个失败的测试来重现错误
2. 验证测试失败(确认错误存在)
3. 用最小的代码更改修复错误
4. 验证测试通过
5. 运行完整的测试套件以检查回归
#### 验证
```bash
# 运行特定测试
npm test -- --grep "LoginForm submit"
# 运行相关测试
npm test -- src/components/LoginForm.test.tsx
# 全面回归检查
npm test
约束
- 只修复错误 - 不要重构周围的代码
- 不要更改组件的公共API
- 确保所有现有测试继续通过
---
### 3. 技术债务票务
```markdown
## [TECH-XXX] 重构:{区域} - {改进}
**类型:** 技术债务
**优先级:** {高 | 中 | 低}
**点数:** {3 | 5 | 8}
**标签:** {重构,性能,可维护性,测试}
---
### 问题陈述
{当前实现有什么问题,为什么重要。
包括具体痛点:慢CI,频繁的错误,开发者困惑。}
### 当前状态
- 文件:`{路径}` ({N}行)
- 测试覆盖率:{X}%
- 圈复杂度:{N}
- 相关错误:{PROJ-XXX, PROJ-YYY}
- 痛苦频率:{这个问题多久导致一次问题}
### 建议更改
{具体应该改变什么以及为什么这种方法。}
### 验收标准
- [ ] {具体结构更改完成}
- [ ] 所有现有测试通过而不需要修改测试断言
- [ ] 公共API没有变化(现有消费者不受影响)
- [ ] 测试覆盖率 >= {X}%
- [ ] {可衡量的改进指标}
### 风险评估
- 风险等级:{低 | 中 | 高}
- 缓解措施:{运行完整回归,部署标志背后等}
### 商业理由
{为什么现在值得做。例如,"将平均错误修复时间从4小时减少到1小时"或"启用即将推出的功能PROJ-XXX,需要清晰的分离。"}
---
### Claude Code上下文
#### 相关文件
- `{file}` - 当前实现要重构
- `{test file}` - 现有测试(不能破坏)
- `{dependent file}` - 被重构的API的消费者
#### 模式参考
按照 `{good example file}` 中建立的模式进行新结构。
#### 约束
- 不要更改公共API或导出
- 不要修改测试断言(测试应该像以前一样通过)
- 不要引入新依赖
- 保持向后兼容性
#### 验证
```bash
# 现有测试必须不变通过
npm test
# 无类型错误
npm run typecheck
# 检查清洁
npm run lint
# 覆盖目标
npm test -- --coverage
---
### 4. 史诗分解票务
```markdown
## [EPIC-XXX] {史诗名称}
**类型:** 史诗
**优先级:** {关键 | 高 | 中}
**目标:** {Sprint/milestone}
---
### 目标
{一段:这个史诗实现了什么以及为什么重要。}
### 成功指标
- {可衡量的结果1}
- {可衡量的结果2}
### 用户工作流程
{这个史诗涵盖的用户旅程,细分为步骤。}
1. {步骤1:发现/入口}
2. {步骤2:核心行动}
3. {步骤3:完成/结果}
### 票务分解
| # | 票务 | 类型 | 点数 | 依赖关系 |
|---|--------|------|--------|-------------|
| 1 | {标题} | 功能 | 3 | 无 |
| 2 | {标题} | 功能 | 5 | #1 |
| 3 | {标题} | 功能 | 3 | 无 |
| 4 | {标题} | 功能 | 2 | #2, #3 |
| 5 | {标题} | 技术债务 | 3 | 无 |
### 分片策略
{如何将史诗分解。参考使用的技术。}
### 代理团队映射
{如果使用代理团队,功能如何映射到代理。}
- 功能代理1:票务#1, #2
- 功能代理2:票务#3, #4
- 并行执行:#1和#3可以同时运行
- 顺序:#2依赖于#1,#4依赖于#2和#3
史诗分片技术
当将史诗分解为票务时,使用这些策略之一:
| 技术 | 何时使用 | 示例 |
|---|---|---|
| 按工作流程步骤 | 清晰的用户旅程 | 浏览 > 播放 > 保存 > 分享 |
| 按数据变化 | 多种数据类型 | 文本帖子,图像,视频 |
| 按用户角色 | 不同权限 | 匿名,认证,管理员 |
| 按CRUD | 数据操作 | 创建,读取,更新,删除 |
| 快乐路径第一 | 增量交付 | 成功流程第一,然后错误 |
| 按边界 | 系统集成 | 前端,API,数据库分别 |
经验法则
- 每个票务:1-3天的工作量,对于一个开发人员/代理
- 超过5个验收标准 = 分割票务
- 超过8个故事点 = 绝对分割
- 每个票务应该是独立部署的(即使在标志后面)
- 票务顺序:最简单,最基础的首先
Claude Code就绪清单
在票务准备好让AI代理执行之前,验证:
┌─────────────────────────────────────────────────────────────────┐
│ CLAUDE CODE READY CHECKLIST │
│ ────────────────────────────────────────────────────────────── │
│ │
│ CONTEXT │
│ ☐ 列出相关文件及其完整路径 │
│ ☐ 模式参考指向要遵循的真实文件 │
│ ☐ API合同定义(请求/响应形状) │
│ ☐ 数据库更改指定(表,列,迁移) │
│ ☐ 环境变量列出(现有+新) │
│ │
│ SCOPE │
│ ☐ 范围外部分明确说明不做什么 │
│ ☐ 约束部分列出不修改的文件/模块 │
│ ☐ 票务涵盖一个逻辑更改(原子) │
│ ☐ 估计在 ≤ 5个故事点 │
│ │
│ VERIFICATION │
│ ☐ 提供测试命令(确切命令,而不是“运行测试”) │
│ ☐ 提供检查命令 │
│ ☐ 提供类型检查命令 │
│ ☐ 验收标准是Given-When-Then或复选框 │
│ ☐ 每个标准可以独立通过/失败测试 │
│ │
│ QUALITY │
│ ☐ 标题是命令动词+对象+上下文 │
│ ☐ 标题在80个字符以下 │
│ ☐ 描述解释WHY,不仅仅是WHAT │
│ ☐ 2-5个验收标准(不多) │
│ ☐ 没有模糊的语言(“快速”,“良好的用户体验”,“清洁”) │
│ │
│ 如果任何框未勾选,则票务不就绪。 │
└─────────────────────────────────────────────────────────────────┘
反模式(永远不要这样做)
1. 只有标题的票务
标题:修复登录
描述:(空)
**为什么失败:**没有上下文,没有验收标准,没有文件引用。Claude Code会猜测并可能猜错。
2. 小说
标题:实施新的入职培训
描述:(3页混合UI,后端,分析,电子邮件和未来的想法)
**为什么失败:**不大,不独立。代理团队无法并行化这个。分成5+票务。
3. 模糊要求
验收标准:
- 应该是快速的
- UX应该是好的
- 应该在移动设备上工作
**为什么失败:**不可测量,不可测试。替换为:“响应时间 < 200ms”, “通过WCAG 2.1 AA”, “在320px视口中没有水平滚动。”
4. 过度指定的解决方案
标题:使用Redis缓存用户会话
描述:安装Redis,配置连接池,设置TTL为3600...
**为什么失败:**而不是问题,开处方解决方案。应该描述"会话查找需要500ms,需要 < 50ms",让代理选择方法。
5. 缺少文件的票务
描述:更新认证模块以支持OAuth。
为什么对AI失败:“认证模块”可能是20个文件。Claude Code需要:src/services/auth.ts, src/middleware/auth.ts, src/routes/auth.ts - 具体路径。
6. 没有验证的票务
验收标准:
- OAuth登录有效
- 用户可以使用Google登录
**为什么失败:**没有测试命令,没有验证步骤。当Claude Code可以验证自己的工作时,它会表现得更好。
好与坏的例子
坏:模糊的功能票务
标题:向API添加速率限制
描述:我们需要在端点上进行速率限制。
好:Claude Code就绪功能票务
标题:向/api/generate端点添加滑动窗口速率限制器
用户故事:
作为API消费者,我希望请求被速率限制
以便在重负载下服务保持可用。
验收标准:
AC1: 假设经过身份验证的用户发出请求,
当他们每分钟超过10个请求时,
那么返回429与Retry-After头。
AC2: 假设速率限制的用户,
当窗口到期时,
那么请求再次成功。
AC3: 假设未经身份验证的请求,
当它击中/api/generate时,
那么返回401(速率限制仅适用于认证用户)。
Claude Code上下文:
- 模式:遵循 `src/middleware/throttle.ts` 中的中间件结构
- 文件:创建 `src/middleware/rateLimit.ts`
- 测试:创建 `tests/middleware/rateLimit.test.ts`
- 路由:修改 `src/api/routes/generate.ts` 添加中间件
- 约束:不要修改现有的中间件或其他端点
验证:
npm test -- --grep "rate-limit"
npm run lint
npm run typecheck
将票务映射到代理团队
当使用代理团队工作流程时,票务直接映射到10任务管道:
| 票务部分 | 映射到 | 代理 |
|---|---|---|
| 标题 + 描述 | 任务1:{name}-spec |
功能代理 |
| 验收标准 | 任务3:{name}-tests |
功能代理(从AC编写测试) |
| 模式参考 | 任务5:{name}-implement |
功能代理(遵循模式) |
| 验证部分 | 任务6-7:验证 + 验证 | 质量代理 + 功能代理 |
| 约束 | 贯穿始终 | 所有代理 |
| Claude Code上下文 | 在开始时加载 | 功能代理首先阅读 |
票务 → 代理团队流程
1. 使用上述模板创建票务
2. 票务成为项目规格中的特