Operation name follows pattern (get/list/search/create/update/delete)
Summary uses "Retrieve" for get/list operations
Description added from vendor documentation
NO error responses (only 200/201)
Properties are camelCase
Nested objects use $ref
Code Generation Phase
Ran npm run clean && npm run generate
Generation succeeded without errors
New types created in generated/
No InlineResponse types generated
Implementation Phase
Method added to producer class
Using generated types (NO Promise)
Mappers implemented for field conversions
Error handling using core types
No TypeScript compilation errors
Testing Phase
Unit test file created/updated
Integration test file created/updated
At least 3 test cases for the operation
Success case tested
Error cases tested
Mocks properly configured
Validation Phase
All tests passing (npm test)
No regression in existing tests
Build successful (npm run build)
Dependencies locked (npm run shrinkwrap)
npm-shrinkwrap.json created
No linting errors
Documentation Phase
Operation documented in code
Test names descriptive
Any special behavior noted
🚫 Immediate Failure Conditions
Task FAILS if:
Operation name contains 'describe'
STOP immediately, use 'get' instead
API spec contains 4xx or 5xx responses
DELETE all error responses
Framework handles errors automatically
Skipped generation step
TASK FAILED - must run npm run clean && npm run generate
No tests written
TASK FAILED - tests are mandatory
Tests not run
TASK FAILED - must execute npm test
Build not verified
TASK FAILED - must execute npm run build
Dependencies not locked
TASK FAILED - must execute npm run shrinkwrap
Used Promise<any> in signatures
TASK FAILED - use generated types
Stopped before Gate 6
TASK INCOMPLETE - continue working
Schema used in both nested and direct contexts without separation
If schema has 10+ properties AND is referenced by other schemas AND has its own endpoint
CREATE separate {Schema}Summary for nested usage
See api-specification.md Rule #19
Hardcoded test values in integration tests
ALL test values (IDs, names, etc.) MUST be in .env
Export from test/integration/Common.ts
Import and use in integration tests
NEVER hardcode: const userId = '12345' ❌
ALWAYS use .env: const userId = TEST_USER_ID ✅
See testing.md Rule #7
Red Flags (Incomplete Work)
Watch for these signs:
No mention of tests - MAJOR red flag
"I've added the operation" without test confirmation
No npm test output shown
No build validation
Jumping to "done" after implementation
User Should NEVER Have To Say
"Now write tests"
"Did you test it?"
"Run the tests"
"Does it build?"
"You forgot the tests"
If user has to remind about tests: TASK HAS FAILED
Complete Execution Example
✅ OPERATION COMPLETE: getAccessToken
Gate 1 - API Specification: ✅
- Operation: getAccessToken (uses 'get', not 'describe')
- Summary: "Retrieve an access token"
- Description from vendor docs included
- Response: 200 only (no error codes)
- All properties camelCase
Gate 2 - Type Generation: ✅
- Ran: npm run clean && npm run generate
- Generated: AccessToken interface
- No InlineResponse types
- Exit code: 0
Gate 3 - Implementation: ✅
- Added to AccessTokenProducer
- Signature: Promise<AccessToken> (not any)
- Mappers handle snake_case → camelCase
- Error handling uses core errors
Gate 4 - Test Creation: ✅
- Unit tests: test/AccessTokenProducerTest.ts (4 cases)
- Integration: test/integration/AccessTokenIntegrationTest.ts (2 cases)
- Mock responses configured
Gate 5 - Test Execution: ✅
- Ran: npm test
- Result: 6 passing
- No regressions
- Exit code: 0
Gate 6 - Build: ✅
- Ran: npm run build
- Result: Success
- No errors
- Exit code: 0
- Ran: npm run shrinkwrap
- npm-shrinkwrap.json created
- Dependencies locked
Operation is fully implemented, tested, and verified.
Enforcement Rules Summary
Rule
Violation = Task Failure
NEVER use 'describe' prefix
✅ Yes
ONLY 200/201 responses
✅ Yes
ALWAYS run generate after API changes
✅ Yes
ALWAYS write tests
✅ Yes
ALWAYS run tests
✅ Yes
ALWAYS build and verify
✅ Yes
ALWAYS run shrinkwrap
✅ Yes
NO Promise<any> types
✅ Yes
Quick Validation Script
#!/bin/bash
# validate-operation.sh
echo "🚦 Validating operation completion..."
FAILED=0
# Gate 1: API Spec
if grep -E "describe[A-Z]" api.yml > /dev/null 2>&1; then
echo "❌ Gate 1 FAILED: 'describe' found in api.yml"
FAILED=1
fi
if grep "nullable:" api.yml > /dev/null 2>&1; then
echo "❌ Gate 1 FAILED: 'nullable' found in api.yml"
FAILED=1
fi
# Check for schema context separation issues
nested_schemas=$(yq eval '.components.schemas[] | .. | select(type == "string" and test("#/components/schemas/")) | capture("#/components/schemas/(?<schema>.+)").schema' api.yml 2>/dev/null | sort -u)
endpoint_schemas=$(yq eval '.paths.*.*.responses.*.content.*.schema["$ref"]' api.yml 2>/dev/null | grep -o '[^/]*$' | sort -u)
for schema in $nested_schemas; do
if echo "$endpoint_schemas" | grep -q "^${schema}$"; then
prop_count=$(yq eval ".components.schemas.${schema}.properties | length" api.yml 2>/dev/null)
if [ "$prop_count" -gt 10 ] 2>/dev/null; then
echo "⚠️ WARNING: Schema '${schema}' used in BOTH nested and direct contexts with ${prop_count} properties"
echo " Consider creating '${schema}Summary' for nested usage (see api-specification.md Rule #19)"
fi
fi
done
# Gate 2: Generation
if [ ! -d "generated" ]; then
echo "❌ Gate 2 FAILED: No generated directory"
FAILED=1
fi
# Gate 3: Implementation
if grep "Promise<any>" src/*.ts > /dev/null 2>&1; then
echo "❌ Gate 3 FAILED: Promise<any> found"
FAILED=1
fi
# Gate 4: Tests exist
if ! find test -name "*Test.ts" | grep -q .; then
echo "❌ Gate 4 FAILED: No test files"
FAILED=1
fi
# Gate 4b: No hardcoded test values in integration tests
if [ -d "test/integration" ]; then
if grep -E "(const|let|var) [a-zA-Z]*[Ii]d = ['\"][0-9]+['\"]" test/integration/*.ts > /dev/null 2>&1; then
echo "❌ Gate 4 FAILED: Hardcoded test values in integration tests"
echo " All test values must be in .env and imported from Common.ts"
FAILED=1
fi
fi
# Gate 5: Tests pass
if ! npm test > /dev/null 2>&1; then
echo "❌ Gate 5 FAILED: Tests failing"
FAILED=1
fi
# Gate 6: Build passes
if ! npm run build > /dev/null 2>&1; then
echo "❌ Gate 6 FAILED: Build failing"
FAILED=1
fi
# Gate 6b: Shrinkwrap dependencies
if ! npm run shrinkwrap > /dev/null 2>&1; then
echo "❌ Gate 6 FAILED: Shrinkwrap failing"
FAILED=1
fi
if [ ! -f "npm-shrinkwrap.json" ]; then
echo "❌ Gate 6 FAILED: npm-shrinkwrap.json not created"
FAILED=1
fi
if [ $FAILED -eq 0 ]; then
echo "✅ ALL GATES PASSED - Operation complete!"
else
echo "🚨 FAILED - Fix issues and re-validate"
exit 1
fi
Remember
GATES ARE NOT OPTIONAL
Every operation MUST pass through ALL gates sequentially.
No shortcuts. No exceptions. Complete or fail.
1---2name: completion-criteria3description: Completion checklist - when is a task truly done4---56## ✅ Completion Checklist
78Task is ONLY complete when ALL items checked:
910### API Specification Phase
11- [ ] Operation added to api.yml
12- [ ] Operation name follows pattern (get/list/search/create/update/delete)
13- [ ] Summary uses "Retrieve" for get/list operations
14- [ ] Description added from vendor documentation
15- [ ] NO error responses (only 200/201)
16- [ ] Properties are camelCase
17- [ ] Nested objects use $ref
1819### Code Generation Phase
20- [ ] Ran `npm run clean && npm run generate`
21- [ ] Generation succeeded without errors
22- [ ] New types created in generated/
23- [ ] No InlineResponse types generated
2425### Implementation Phase
26- [ ] Method added to producer class
27- [ ] Using generated types (NO Promise<any>)
28- [ ] Mappers implemented for field conversions
29- [ ] Error handling using core types
30- [ ] No TypeScript compilation errors
3132### Testing Phase
33- [ ] Unit test file created/updated
34- [ ] Integration test file created/updated
35- [ ] At least 3 test cases for the operation
36- [ ] Success case tested
37- [ ] Error cases tested
38- [ ] Mocks properly configured
3940### Validation Phase
41- [ ] All tests passing (`npm test`)
42- [ ] No regression in existing tests
43- [ ] Build successful (`npm run build`)
44- [ ] Dependencies locked (`npm run shrinkwrap`)
45- [ ] npm-shrinkwrap.json created
46- [ ] No linting errors
4748### Documentation Phase
49- [ ] Operation documented in code
50- [ ] Test names descriptive
51- [ ] Any special behavior noted
5253## 🚫 Immediate Failure Conditions
5455Task FAILS if:
56571. **Operation name contains 'describe'**
58 - STOP immediately, use 'get' instead
59602. **API spec contains 4xx or 5xx responses**
61 - DELETE all error responses
62 - Framework handles errors automatically
63643. **Skipped generation step**
65 - TASK FAILED - must run `npm run clean && npm run generate`
66674. **No tests written**
68 - TASK FAILED - tests are mandatory
69705. **Tests not run**
71 - TASK FAILED - must execute `npm test`
72736. **Build not verified**
74 - TASK FAILED - must execute `npm run build`
75767. **Dependencies not locked**
77 - TASK FAILED - must execute `npm run shrinkwrap`
78798. **Used `Promise<any>` in signatures**
80 - TASK FAILED - use generated types
81829. **Stopped before Gate 6**
83 - TASK INCOMPLETE - continue working
848510. **Schema used in both nested and direct contexts without separation**
86 - If schema has 10+ properties AND is referenced by other schemas AND has its own endpoint
87 - CREATE separate `{Schema}Summary` for nested usage
88 - See api-specification.md Rule #19
899011. **Hardcoded test values in integration tests**
91 - ALL test values (IDs, names, etc.) MUST be in .env
92 - Export from test/integration/Common.ts
93 - Import and use in integration tests
94 - NEVER hardcode: `const userId = '12345'` ❌
95 - ALWAYS use .env: `const userId = TEST_USER_ID` ✅
96 - See testing.md Rule #7
9798## Red Flags (Incomplete Work)
99100Watch for these signs:
1011021. **No mention of tests** - MAJOR red flag
1032. **"I've added the operation"** without test confirmation
1043. **No `npm test` output shown**
1054. **No build validation**
1065. **Jumping to "done" after implementation**
107108## User Should NEVER Have To Say
109110- "Now write tests"
111- "Did you test it?"
112- "Run the tests"
113- "Does it build?"
114- "You forgot the tests"
115116If user has to remind about tests: **TASK HAS FAILED**
117118## Complete Execution Example
119120```
121✅ OPERATION COMPLETE: getAccessToken
122123Gate 1 - API Specification: ✅
124- Operation: getAccessToken (uses 'get', not 'describe')
125- Summary: "Retrieve an access token"
126- Description from vendor docs included
127- Response: 200 only (no error codes)
128- All properties camelCase
129130Gate 2 - Type Generation: ✅
131- Ran: npm run clean && npm run generate
132- Generated: AccessToken interface
133- No InlineResponse types
134- Exit code: 0
135136Gate 3 - Implementation: ✅
137- Added to AccessTokenProducer
138- Signature: Promise<AccessToken> (not any)
139- Mappers handle snake_case → camelCase
140- Error handling uses core errors
141142Gate 4 - Test Creation: ✅
143- Unit tests: test/AccessTokenProducerTest.ts (4 cases)
144- Integration: test/integration/AccessTokenIntegrationTest.ts (2 cases)
145- Mock responses configured
146147Gate 5 - Test Execution: ✅
148- Ran: npm test
149- Result: 6 passing
150- No regressions
151- Exit code: 0
152153Gate 6 - Build: ✅
154- Ran: npm run build
155- Result: Success
156- No errors
157- Exit code: 0
158- Ran: npm run shrinkwrap
159- npm-shrinkwrap.json created
160- Dependencies locked
161162Operation is fully implemented, tested, and verified.
163```
164165## Enforcement Rules Summary
166167| Rule | Violation = Task Failure |
168|------|--------------------------|
169| NEVER use 'describe' prefix | ✅ Yes |
170| ONLY 200/201 responses | ✅ Yes |
171| ALWAYS run generate after API changes | ✅ Yes |
172| ALWAYS write tests | ✅ Yes |
173| ALWAYS run tests | ✅ Yes |
174| ALWAYS build and verify | ✅ Yes |
175| ALWAYS run shrinkwrap | ✅ Yes |
176| NO `Promise<any>` types | ✅ Yes |
177178## Quick Validation Script
179180```bash
181#!/bin/bash
182# validate-operation.sh
183184echo "🚦 Validating operation completion..."
185186FAILED=0
187188# Gate 1: API Spec
189if grep -E "describe[A-Z]" api.yml > /dev/null 2>&1; then
190 echo "❌ Gate 1 FAILED: 'describe' found in api.yml"
191 FAILED=1
192fi
193194if grep "nullable:" api.yml > /dev/null 2>&1; then
195 echo "❌ Gate 1 FAILED: 'nullable' found in api.yml"
196 FAILED=1
197fi
198199# Check for schema context separation issues
200nested_schemas=$(yq eval '.components.schemas[] | .. | select(type == "string" and test("#/components/schemas/")) | capture("#/components/schemas/(?<schema>.+)").schema' api.yml 2>/dev/null | sort -u)
201endpoint_schemas=$(yq eval '.paths.*.*.responses.*.content.*.schema["$ref"]' api.yml 2>/dev/null | grep -o '[^/]*$' | sort -u)
202for schema in $nested_schemas; do
203 if echo "$endpoint_schemas" | grep -q "^${schema}$"; then
204 prop_count=$(yq eval ".components.schemas.${schema}.properties | length" api.yml 2>/dev/null)
205 if [ "$prop_count" -gt 10 ] 2>/dev/null; then
206 echo "⚠️ WARNING: Schema '${schema}' used in BOTH nested and direct contexts with ${prop_count} properties"
207 echo " Consider creating '${schema}Summary' for nested usage (see api-specification.md Rule #19)"
208 fi
209 fi
210done
211212# Gate 2: Generation
213if [ ! -d "generated" ]; then
214 echo "❌ Gate 2 FAILED: No generated directory"
215 FAILED=1
216fi
217218# Gate 3: Implementation
219if grep "Promise<any>" src/*.ts > /dev/null 2>&1; then
220 echo "❌ Gate 3 FAILED: Promise<any> found"
221 FAILED=1
222fi
223224# Gate 4: Tests exist
225if ! find test -name "*Test.ts" | grep -q .; then
226 echo "❌ Gate 4 FAILED: No test files"
227 FAILED=1
228fi
229230# Gate 4b: No hardcoded test values in integration tests
231if [ -d "test/integration" ]; then
232 if grep -E "(const|let|var) [a-zA-Z]*[Ii]d = ['\"][0-9]+['\"]" test/integration/*.ts > /dev/null 2>&1; then
233 echo "❌ Gate 4 FAILED: Hardcoded test values in integration tests"
234 echo " All test values must be in .env and imported from Common.ts"
235 FAILED=1
236 fi
237fi
238239# Gate 5: Tests pass
240if ! npm test > /dev/null 2>&1; then
241 echo "❌ Gate 5 FAILED: Tests failing"
242 FAILED=1
243fi
244245# Gate 6: Build passes
246if ! npm run build > /dev/null 2>&1; then
247 echo "❌ Gate 6 FAILED: Build failing"
248 FAILED=1
249fi
250251# Gate 6b: Shrinkwrap dependencies
252if ! npm run shrinkwrap > /dev/null 2>&1; then
253 echo "❌ Gate 6 FAILED: Shrinkwrap failing"
254 FAILED=1
255fi
256257if [ ! -f "npm-shrinkwrap.json" ]; then
258 echo "❌ Gate 6 FAILED: npm-shrinkwrap.json not created"
259 FAILED=1
260fi
261262if [ $FAILED -eq 0 ]; then
263 echo "✅ ALL GATES PASSED - Operation complete!"
264else
265 echo "🚨 FAILED - Fix issues and re-validate"
266 exit 1
267fi
268```
269270## Remember
271272**GATES ARE NOT OPTIONAL**
273274Every operation MUST pass through ALL gates sequentially.
275No shortcuts. No exceptions. Complete or fail.
Run npx skillmds add majiayu000/completion-criteria in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Completion checklist - when is a task truly done It is listed under Productivity on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: reads secrets. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
majiayu000 (@majiayu000) published this skill. Their other Agent Skills are listed on their SkillMD profile.