Use when spec and code diverge - AI analyzes mismatches, recommends update spec vs fix code with reasoning, handles evolution with user control or auto-updates
From spexnpx claudepluginhub rhuss/cc-spex --plugin spexThis skill uses the workspace's default tool permissions.
Handle spec/code mismatches through AI-guided analysis and user-controlled evolution.
Specs WILL diverge from code. This is normal and healthy. The question is: which should change?
This skill detects divergence, analyzes the mismatch, recommends resolution, and executes the change.
Use this skill when:
Auto-triggered by:
spex:review-code (when deviations found)spex:verification-before-completion (when compliance fails)Don't use this skill when:
/speckit.specifyspex:spec-refactoringEnsure spec-kit is initialized:
{Skill: spec-kit}
If spec-kit prompts for restart, pause this workflow and resume after restart.
If no spec is specified, discover available specs:
# List all specs in the project
fd -t f "spec.md" specs/ 2>/dev/null | head -20
If specs found: Present list and ask user to select one using AskUserQuestion.
Example:
Found 2 specs in this project:
1. specs/0001-user-auth/spec.md
2. specs/0002-api-gateway/spec.md
Which spec needs evolution/reconciliation?
If no specs found: Inform user:
No specs found in specs/ directory.
Spec evolution requires an existing spec to evolve.
Use `spex:brainstorm` or `/speckit.specify` to create one first.
Before analyzing or modifying, verify spec-kit artifacts exist:
# Check what artifacts exist for this feature
SPEC_DIR="specs/[feature-dir]" # Replace with actual spec directory
echo "Checking for existing artifacts..."
[ -f "$SPEC_DIR/spec.md" ] && echo "✓ spec.md exists" || echo "❌ spec.md missing"
[ -f "$SPEC_DIR/plan.md" ] && echo "✓ plan.md exists" || echo "○ plan.md not present"
[ -f "$SPEC_DIR/tasks.md" ] && echo "✓ tasks.md exists" || echo "○ tasks.md not present"
If spec.md is missing: Cannot proceed with evolution. Use /speckit.specify first.
If plan.md or tasks.md exist:
/speckit.plan - Regenerate plan/speckit.tasks - Regenerate tasks/speckit.analyze - Verify consistencyCRITICAL: Never manually edit plan.md or tasks.md. Always regenerate via /speckit. commands after spec changes.*
Identify all spec/code divergences:
# Read spec
cat specs/features/[feature-name].md
# Compare to implementation
# For each requirement in spec:
# - What does spec say?
# - What does code do?
# - Do they match?
Categorize each mismatch:
Document all mismatches with:
For each mismatch, determine:
Type:
Severity:
Impact:
For each mismatch, recommend:
Option A: Update Spec
Option B: Fix Code
Option C: Clarify Spec
Provide reasoning for recommendation:
Decision flow:
Is this mismatch trivial/minor AND auto-update enabled?
Yes → Auto-update with notification
No → Ask user to decide
User decides:
A) Update spec
B) Fix code
C) Clarify spec
D) Defer (mark as known deviation)
Check user configuration:
{
"spex": {
"auto_update_spec": {
"enabled": true,
"threshold": "minor", // "none", "minor", "moderate"
"notify": true
}
}
}
Thresholds:
none: Never auto-updateminor: Auto-update trivial/minor mismatchesmoderate: Include non-breaking behavioral changesOption A: Update Spec
# Update spec
vim specs/features/[feature].md
# Add changelog entry
echo "- YYYY-MM-DD: Updated [requirement] to include [change]" >> specs/features/[feature].md
# Commit
git add specs/features/[feature].md
git commit -m "Update spec: [change]
Implementation revealed [reason for change].
Previous: [old requirement]
Updated: [new requirement]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>"
Option B: Fix Code
# Fix code
[Make changes to match spec]
# Update tests
[Adjust tests to match spec]
# Verify compliance
[Run spex:verification-before-completion]
# Commit
git add [files]
git commit -m "Fix: Align [component] with spec
Code was [what it did], spec requires [what spec says].
Updated to match spec requirement: [spec section]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>"
Option C: Clarify Spec
Option D: Defer
After resolution:
# Re-check spec compliance
# Ensure mismatch is resolved
# Verify no new mismatches introduced
If spec was updated (Options A or C), regenerate dependent artifacts:
Regenerate plan and tasks to stay in sync:
If plan.md exists, invoke /speckit.plan to regenerate it.
If tasks.md exists, invoke /speckit.tasks to regenerate it.
Invoke /speckit.analyze to verify consistency across all artifacts.
VERIFICATION CHECKPOINT:
After regeneration, verify artifacts are in sync using /speckit.analyze.
Confirm:
Use TodoWrite to track:
[During verification]
Spec compliance check: 95%
Mismatch detected:
**Mismatch 1: Response includes timestamp (MINOR)**
- **Spec says:** Return `{ id, name, email }`
- **Code does:** Returns `{ id, name, email, updated_at }`
- **Location:** src/api/users.ts:45, specs/features/user-api.md#response
**Analysis:**
- Type: Behavioral (but non-breaking addition)
- Severity: Minor
- Impact: Non-breaking, adds useful information
**Recommendation: Update Spec (Option A)**
**Reasoning:**
- `updated_at` is standard practice for update endpoints
- Provides useful information to clients
- Non-breaking addition (clients can ignore it)
- Implementation is better than spec
**User config:** auto_update_spec.threshold = "minor"
**Action:** Auto-updating spec...
Updated specs/features/user-api.md:
- Added `updated_at` to response format
- Changelog: "2025-11-10: Added updated_at timestamp to responses"
✅ Spec updated
✅ Compliance now 100%
✅ Committed to git
Notification: Spec auto-updated with updated_at field (minor addition)
[During code review]
Spec compliance check: 85%
Mismatch detected:
**Mismatch 1: Validation behavior difference (MAJOR)**
- **Spec says:** "Reject requests with invalid avatar_url, return 422"
- **Code does:** "Accept invalid URLs, set avatar_url to null, return 200"
- **Location:** src/middleware/validation.ts:78, specs/features/user-profile.md#validation
**Analysis:**
- Type: Behavioral (changes error handling)
- Severity: Major
- Impact: User-facing, affects API contract
**Options:**
**A) Update Spec - Lenient validation**
- Pros: More user-friendly, prevents frustration
- Cons: Inconsistent with other validation (strict)
- Risk: Users might not know avatar failed
**B) Fix Code - Strict validation**
- Pros: Consistent with spec and other validation
- Cons: Worse UX when URL is invalid
- Risk: None (matches spec)
**C) Clarify Spec - Explicit fallback**
- Pros: Best of both (validate but handle gracefully)
- Cons: More complex
- Risk: None
**Recommendation: Option C**
**Reasoning:**
Best practice is to validate input but handle gracefully. Update spec to explicitly define fallback behavior: validate URL, set to null if invalid, log warning, return success with indication.
Which option do you prefer?
User: C - explicit fallback
You: Perfect. Updating spec to clarify fallback behavior...
Updated spec:
## Validation Rules
### avatar_url
- Must be valid URL format if provided
- **Fallback behavior:** If URL validation fails:
- Set avatar_url to null
- Log validation error
- Return 200 (success) with warning in response
- Response includes: `warnings: ["avatar_url invalid, set to null"]`
Code now matches clarified spec ✅
Spec compliance: 100%
Committed to git ✅
[During verification]
Spec compliance check: 90%
Mismatch detected:
**Mismatch 1: Missing error handling (CRITICAL)**
- **Spec says:** "Handle database connection errors with retry logic (3 attempts)"
- **Code does:** "Single attempt, fails immediately on error"
- **Location:** src/db/client.ts:34, specs/features/data-persistence.md#error-handling
**Analysis:**
- Type: Architectural (missing reliability mechanism)
- Severity: Critical
- Impact: Production reliability risk
**Recommendation: Fix Code (Option B)**
**Reasoning:**
- Spec defines critical reliability requirement
- Single-attempt fails too easily (production risk)
- Retry logic is standard practice
- Code is missing required feature
**No user decision needed - critical spec requirement missing**
Fixing code to implement retry logic...
```typescript
// Added retry logic
async function queryWithRetry(sql, params, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
return await db.query(sql, params);
} catch (error) {
if (i === attempts - 1) throw error;
await sleep(1000 * (i + 1)); // Exponential backoff
}
}
}
Tests updated to verify retry behavior ✅ Spec compliance: 100% ✅
Committed code fix ✅
## Auto-Update Configuration
### Recommended Settings
**For solo projects:**
```json
{
"auto_update_spec": {
"enabled": true,
"threshold": "minor",
"notify": true
}
}
For team projects:
{
"auto_update_spec": {
"enabled": true,
"threshold": "none", // Always ask
"notify": true
}
}
For experimental work:
{
"auto_update_spec": {
"enabled": true,
"threshold": "moderate",
"notify": true
}
}
Mismatch: Spec says "return error", code returns detailed error with context
Resolution: Update spec (minor)
Mismatch: Spec doesn't mention empty array, code handles it
Resolution: Clarify spec (add edge case)
Mismatch: Spec doesn't specify caching, code adds cache
Resolution: Update spec (moderate)
Mismatch: Spec implies synchronous, code is async
Resolution: Ask user (major)
Spec evolution is normal and healthy.
The goal is alignment, not rigidity.
Always provide reasoning:
Trust the process:
Spec and code in sync = quality software.