| name | openapi-critical-rules |
| description | The 12 critical OpenAPI rules that cause immediate task failure if violated |
12 Critical API Specification Rules
These 12 rules cause IMMEDIATE TASK FAILURE if violated.
Rule 1: Root Level Restrictions
FORBIDDEN at root level in api.yml:
servers: - NO server configuration at root
security: - NO security at root
securitySchemes: - Belongs in components only
servers:
- url: https://api.example.com
security:
- bearerAuth: []
openapi: 3.0.0
info:
title: Service API
paths:
...
components:
securitySchemes:
...
WHY: Root-level servers and security conflict with hub's connection management.
Rule 2: Resource Naming Consistency
MANDATORY: Singular nouns for tags and schemas
tags:
- name: user
- name: organization
- name: webhook
components:
schemas:
User:
...
Organization:
...
tags:
- name: users
- name: orgs
WHY: Consistent naming convention across all modules.
Rule 3: Operation Coverage
MANDATORY: ALL operations from product analysis MUST be in API spec
Process:
- Product specialist identifies N operations
- API architect MUST include all N operations
- Zero operations may be skipped
Validation:
yq eval '.paths.*.* | select(has("operationId")) | .operationId' api.yml | wc -l
IF MISMATCH: Add missing operations or document why excluded.
Rule 4: Parameter Reuse
RULE: If 2+ operations use same parameter → Move to components
components:
parameters:
userId:
name: userId
in: path
required: true
schema:
type: string
paths:
/users/{userId}:
get:
parameters:
- $ref: '#/components/parameters/userId'
/users/{userId}/profile:
get:
parameters:
- $ref: '#/components/parameters/userId'
paths:
/users/{userId}:
get:
parameters:
- name: userId
in: path
required: true
schema:
type: string
/users/{userId}/profile:
get:
parameters:
- name: userId
in: path
required: true
schema:
type:
WHY: DRY principle, consistency, easier updates.
Rule 5: Property Naming - camelCase ONLY
MANDATORY: ALL properties in camelCase
User:
properties:
userId:
type: string
firstName:
type: string
createdAt:
type: string
format: date-time
User:
properties:
user_id:
type: string
first_name:
type: string
created-at:
type: string
Validation:
grep "_" api.yml | grep -v "x-" | grep -v "#"
WHY: TypeScript/JavaScript convention, generated code uses camelCase.
Rule 6: Parameter Naming - orderBy/orderDir
MANDATORY: Sorting parameters use these exact names
parameters:
- name: orderBy
in: query
schema:
type: string
enum: [name, createdAt, updatedAt]
- name: orderDir
in: query
schema:
type: string
enum: [asc, desc]
default: asc
parameters:
- name: sortBy
- name: sortField
- name: direction
- name: order
WHY: Framework expects these exact parameter names.
Rule 7: Path Parameters - Descriptive Types
MANDATORY: Path parameters use descriptive names
/users/{userId}
/organizations/{organizationId}
/webhooks/{webhookId}
/users/{id}
/organizations/{org}
/webhooks/{wid}
WHY: Clear, self-documenting paths. Prevents parameter conflicts.
Rule 8: Resource Identifier Priority
MANDATORY: Use this order for resource identification:
id (UUID, integer, string ID)
name (if unique identifier)
- Other unique fields
/users/{userId}
/templates/{templateName}
/users/{email}
WHY: Stable identifiers for API operations.
Rule 9: Tags - Singular Nouns
MANDATORY: Tags are singular nouns matching resource name
paths:
/users:
get:
tags:
- user
/users/{userId}:
get:
tags:
- user
paths:
/users:
get:
tags:
- users
- Users
WHY: Consistent tag naming, generates clean Producer class names.
Rule 10: Method Naming - operationId vs x-method-name
PATTERN:
operationId: Full descriptive ID (getUser, listUsers, createUser)
x-method-name: Actual TypeScript method name (must match operationId pattern)
paths:
/users/{userId}:
get:
operationId: getUser
x-method-name: getUser
summary: Retrieve user by ID
/users:
get:
operationId: listUsers
x-method-name: listUsers
summary: Retrieve list of users
paths:
/users/{userId}:
get:
operationId: describeUser
x-method-name: get_user
VERBS:
get - Retrieve single resource
list - Retrieve collection
search - Query with filters
create - Create new resource
update - Modify existing resource
delete - Remove resource
WHY: Consistent method naming, proper TypeScript generation.
Rule 11: Pagination - pageTokenParam from Core
MANDATORY: Use core pagination parameter for token-based paging
paths:
/users:
get:
parameters:
- $ref: './node_modules/@zerobias-org/types-core/schema/pageTokenParam.yml'
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
parameters:
- name: nextToken
- name: cursor
- name: continuationToken
WHY: Framework expects standard pageToken parameter name.
Rule 12: Response Codes - 200/201 ONLY
MANDATORY: ONLY success responses in API specification
responses:
'200':
description: User retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'401':
description: Unauthorized
'404':
description: Not found
'500':
description: Server error
Validation:
grep -E "'40[0-9]'|'50[0-9]'" api.yml
WHY: Framework handles errors automatically. Error responses in spec cause generation issues.
Summary Table
| Rule # | Topic | Violation = Immediate Failure |
|---|
| 1 | Root Level Restrictions | ✅ Yes |
| 2 | Resource Naming | ✅ Yes |
| 3 | Operation Coverage | ✅ Yes |
| 4 | Parameter Reuse | ✅ Yes |
| 5 | Property Naming (camelCase) | ✅ Yes |
| 6 | Parameter Naming (orderBy/orderDir) | ✅ Yes |
| 7 | Path Parameters (descriptive) | ✅ Yes |
| 8 | Resource Identifier Priority | ✅ Yes |
| 9 | Tags (singular) | ✅ Yes |
| 10 | Method Naming (operationId) | ✅ Yes |
| 11 | Pagination (pageTokenParam) | ✅ Yes |
| 12 | Response Codes (200/201 only) | ✅ Yes |
Validation Checklist
Before proceeding past Gate 1, verify ALL 12 rules:
Quick Validation Script
#!/bin/bash
FAILED=0
if grep "_" api.yml | grep -v "x-" | grep -v "#" > /dev/null 2>&1; then
echo "❌ Rule 5 FAILED: snake_case found in properties"
FAILED=1
fi
if grep -E "describe[A-Z]" api.yml > /dev/null 2>&1; then
echo "❌ Rule 10 FAILED: 'describe' prefix found"
FAILED=1
fi
if grep -E "'40[0-9]'|'50[0-9]'" api.yml > /dev/null 2>&1; then
echo "❌ Rule 12 FAILED: Error responses found"
FAILED=1
fi
if [ $FAILED -eq 0 ]; then
echo "✅ Critical rules validation passed"
else
echo "🚨 FIX ISSUES BEFORE PROCEEDING"
exit 1
fi
References
- Full API specification rules: @.claude/rules/api-spec-*.md
- Gate 1 validation: @.claude/rules/gate-1-api-spec.md
- API Architect agent: @.claude/agents/api-architect.md