ワンクリックで
define-api-spec
在项目层面定义 API spec。在启动带 API 的项目、api-spec.md 缺失或过时、或跨服务出现 API 不一致时使用。产出 docs/api-spec.md,作为权威的 API contract。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
在项目层面定义 API spec。在启动带 API 的项目、api-spec.md 缺失或过时、或跨服务出现 API 不一致时使用。产出 docs/api-spec.md,作为权威的 API contract。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
FDD 主流程 step 1(规划与拆解)。覆盖两段——plan(与用户弄清需求、经 investigator 调查代码库、定出 milestone、写出 plan.md 并呈现)与 features(把 milestone 拆成 features.json 并过 coverage 闸)。中间的 contract 段交给 harness-stack:fdd-validation-contract。由 harness-stack:fdd 调用。
构建新特性的主流程编排器。契约优先的多 agent 架构——捕获一个 plan,定义可测试的断言,拆解为多个 feature,再用全新上下文的 implementer/reviewer/validator subagent 驱动一个里程碑设闸的执行循环。当一处改动触及多个文件、有多条验收标准、或跨越多个 feature 时使用。主流程分三步,分发给 fdd-planning(含 fdd-validation-contract)/ fdd-execution / fdd-validate。
为一个 plan 撰写 validation contract——把 definition of done 落成一组可测试、用户可观测的 assertion(VAL-<AREA>-NNN),带 persona 与声明的 Evidence。它是 fdd step 1(规划)里的 contract 阶段。契约通过逐 area 的 investigation subagent 与若干轮 adversarial review 构建,而非一人独写。产出 .harness-runtime/plans/<slug>/validation-contract.md,并经由 fdd init-state 播种 validation-state.json。在项目内首次使用时,还会 bootstrap 项目级约定文档 docs/user-test-patterns.md。
规范 git 工作流实践。任何代码改动都适用。在提交、开分支、解决冲突,或需要把多条并行工作线组织起来时使用。
harness-stack 框架的引导纲要(bootstrap doctrine)。在会话开始时自动加载,用以介绍 lifecycle map、golden rules,以及如何挑选正确的 harness-stack:* skill。在一次会话中首次调用任何 harness-stack:* skill 之前,先读它。
复盘一次 harness-stack 使用,把值得上报的摩擦、缺陷或建议提成 GitHub Issue 反馈给上游。在完成一项任务、用完某个 skill 后有意见或改进想法,或想为框架本身留下改进线索时使用。
| name | define-api-spec |
| description | 在项目层面定义 API spec。在启动带 API 的项目、api-spec.md 缺失或过时、或跨服务出现 API 不一致时使用。产出 docs/api-spec.md,作为权威的 API contract。 |
为项目定义 API contract。docs/api-spec.md 规定响应结构、错误格式、状态码、分页、认证、版本管理以及 validation 策略。读这份文件的 agent 或工程师,应当不靠猜就清楚该如何写一个新 endpoint。
docs/api-spec.md 缺失When NOT to use: 没有 API 的项目。不对外部消费方提供服务的内部库或 CLI 工具。
你在定义一份 contract,而不是写文档。
{data, error}、另一些返回 {result, message},那不是 spec——那是混乱。选定一种。DISCOVER ──→ CHALLENGE ──→ DEFINE ──→ APPROVE
│ │ │ │
▼ ▼ ▼ ▼
Read existing Question Write Human
endpoints patterns api-spec confirms
and configs and gaps .md
加载上下文:
docs/architecture.md——理解各 domain 与服务边界docs/api-spec.md 则读它——做更新,不要重写采样现有 endpoint:
跨不同 domain 读 5-10 个 API route handler。对每个,提取:
识别已有工具链:
呈现 discovery 结果:
DISCOVERED API PATTERNS:
Response shape (sampled 8 endpoints):
- Success: { data: {...} } (6/8) → Strong convention
- Error: { error: { code, message } } (5/8) → Strong convention
- Pagination: { data: [...], pagination: { page, totalPages } } (3/4 list endpoints)
Status codes:
- 200 for success, 201 for creation (8/8) → Consistent
- 400 vs 422 for validation (mixed) → Needs decision
Authentication:
- Bearer token via Authorization header (8/8) → Consistent
- Some routes use middleware, some check inline (mixed) → Needs decision
Validation:
- Zod schemas (6/8 endpoints) → Strong convention
- Validation at handler layer (5/8) → Emerging
URL structure:
- /api/v1/<resource> (8/8) → Consistent
- Plural nouns, no verbs (7/8) → Strong convention
INCONSISTENCIES:
1. Two different error response shapes between v1 and v2 routes
2. Pagination: offset-based in /tasks, cursor-based in /events
→ Which patterns are intentional?
对每一个发现的模式:
对每一处不一致:
挑战常见问题:
点出 Hyrum 定律:
任何可观测的行为——包括未记录的怪癖、错误信息文本、时序与顺序——一旦有消费方依赖它,就成了事实上的 contract。
问:「有没有消费方已经在依赖、却未被记录的行为?那些也得写进 spec。」
写 docs/api-spec.md:
# API Specification
**Last Updated:** [date]
## Overview
<!-- 一段话:本项目对外暴露哪些 API、面向谁、
用什么协议(REST、GraphQL、RPC)。 -->
## Base URL & Versioning
<!-- 版本如何工作。把 URL 结构摆出来。 -->
| Environment | Base URL |
|---|---|
| Production | `https://api.example.com/v1` |
| Staging | `https://api-staging.example.com/v1` |
Versioning strategy: [URL path / header / query param].
## Authentication
<!-- 消费方如何认证。把确切的 header 或机制摆出来。 -->
\```
Authorization: Bearer <token>
\```
<!-- 哪些 endpoint 是公开的、哪些是受保护的。 -->
## Response Format
### Success
\```json
{
"data": { ... }
}
\```
### Success (list)
\```json
{
"data": [ ... ],
"pagination": {
"page": 1,
"pageSize": 20,
"totalItems": 142,
"totalPages": 8
}
}
\```
### Error
\```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": [ ... ]
}
}
\```
## Status Codes
| Code | Meaning | 何时使用 |
|---|---|---|
| 200 | OK | 读取或更新成功 |
| 201 | Created | 资源创建成功 |
| 204 | No Content | 删除成功 |
| 400 | Bad Request | 请求语法不合法 |
| 401 | Unauthorized | 缺少或无效的认证 |
| 403 | Forbidden | 已认证但未授权 |
| 404 | Not Found | 资源不存在 |
| 409 | Conflict | 资源重复或版本不匹配 |
| 422 | Unprocessable Entity | validation 失败(语义上不合法) |
| 500 | Internal Server Error | 意外的服务端错误 |
## Error Codes
<!-- 用于 error.code 字段的、应用特定的错误码。 -->
| Code | HTTP Status | Meaning |
|---|---|---|
| VALIDATION_ERROR | 422 | 请求 validation 失败 |
| NOT_FOUND | 404 | 资源不存在 |
| UNAUTHORIZED | 401 | 需要认证 |
| FORBIDDEN | 403 | 权限不足 |
| CONFLICT | 409 | 资源冲突 |
| INTERNAL_ERROR | 500 | 意外的服务端错误 |
## Pagination
<!-- 采用哪种策略:offset-based、cursor-based、还是两者皆有。
给出请求与响应示例。 -->
Request:
\```
GET /api/v1/tasks?page=1&pageSize=20&sortBy=createdAt&sortOrder=desc
\```
Response: see "Success (list)" format above.
## Filtering & Sorting
<!-- 列表 endpoint 如何接收过滤与排序参数。 -->
\```
GET /api/v1/tasks?status=in_progress&assignee=user123&createdAfter=2025-01-01
\```
## URL Conventions
| Pattern | Convention | Example |
|---|---|---|
| Resources | 复数名词,不带动词 | `/api/v1/tasks` |
| Single resource | 资源 + ID | `/api/v1/tasks/:id` |
| Sub-resources | 嵌套在父资源之下 | `/api/v1/tasks/:id/comments` |
| Query params | camelCase | `?sortBy=createdAt&pageSize=20` |
| Actions (non-CRUD) | 带动词的 POST | `POST /api/v1/tasks/:id/archive` |
## Request Validation
<!-- validation 在哪里发生、用什么库。 -->
validation 在 handler 层进行,使用 [Zod/Joi/Pydantic/等]。
- 不合法的请求返回 422 并附错误详情
- validation 之后,内部代码信任这些类型
- 第三方 API 的响应在使用前先经 validation
## Field Conventions
| Pattern | Convention | Example |
|---|---|---|
| Response fields | camelCase | `createdAt`, `userId` |
| Boolean fields | is/has/can 前缀 | `isComplete`, `hasAttachments` |
| Enum values | UPPER_SNAKE | `IN_PROGRESS`, `COMPLETED` |
| Timestamps | ISO 8601 | `2025-01-15T10:30:00Z` |
| IDs | 字符串(UUID 或带前缀) | `usr_abc123` |
## Backward Compatibility
- 新字段是增量且可选的
- 已有字段不改类型、不被移除
- 移除前先标弃用——在响应中标记弃用字段
- 破坏性变更需要一个新的 API 版本
## API Documentation
<!-- endpoint 如何向消费方记录。 -->
以 OpenAPI(Swagger)作为 API 文档标准。维护一个 `openapi.yaml`(或 `openapi.json`)作为 endpoint 定义的唯一事实来源。
- 新增或变更的 endpoint 必须在合并前更新 OpenAPI spec
- OpenAPI spec 记录:路径、参数、请求/响应 schema、错误码
- `docs/api-spec.md` 定义项目级的模式(响应格式、状态码、字段约定);OpenAPI 记录单个 endpoint
写作原则:
API SPEC READY FOR REVIEW:
- Response format: [defined with JSON examples]
- Status codes: [count] mapped
- Error codes: [count] defined
- Pagination: [offset/cursor/both]
- Authentication: [mechanism]
- URL conventions: [defined]
- Validation: [library and strategy]
- API docs: OpenAPI spec [location]
→ This is the API contract for the project.
Approve, or tell me what to change.
spec 描述 API 现在「是」怎样的,而不是它曾经或应该是怎样的。
| 借口 | 现实 |
|---|---|
| 「API 文档以后再补。」 | contract 本身就是文档。先把它定下来——实现随其后。 |
| 「现在还不需要分页。」 | 一旦有人手里有 100+ 条数据,你就需要了。从一开始就加上。 |
| 「PATCH 太麻烦,干脆都用 PUT。」 | PUT 每次都要求传完整对象。客户端做局部更新真正想要的是 PATCH。 |
| 「等需要时再做版本。」 | 没有版本管理的破坏性变更会打挂消费方。从一开始就为扩展而设计。 |
| 「内部 API 不需要 spec。」 | 内部消费方也是消费方。spec 防止耦合、让并行工作成为可能。 |
| 「OpenAPI spec 已经覆盖了。」 | OpenAPI 描述 endpoint。它未必能涵盖错误处理策略、分页模式或字段约定。两者可以共存。 |
/api/createTask、/api/getUsers)docs/api-spec.md