Spec Evolution and Reconciliation
Overview
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.
When to Use
Use this skill when:
- •Code review detects spec/code mismatch
- •Verification finds spec compliance issues
- •Developer explicitly requests evolution
- •Implementation reveals better approach than spec
- •Spec ambiguity discovered during implementation
Auto-triggered by:
- •
sdd:review-code(when deviations found) - •
sdd:verification-before-completion(when compliance fails)
Don't use this skill when:
- •No mismatch exists (everything compliant)
- •Spec doesn't exist yet → Use
/speckit.specify - •Multiple specs need consolidation → Use
sdd:spec-refactoring
Prerequisites
Ensure spec-kit is initialized:
{Skill: spec-kit}
If spec-kit prompts for restart, pause this workflow and resume after restart.
Spec Selection
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 `sdd:brainstorm` or `/speckit.specify` to create one first.
The Process
0. Check Existing Artifacts
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:
- •These were generated by spec-kit and must be kept in sync
- •After modifying the spec, regenerate dependent artifacts using:
- •
/speckit.plan- Regenerate plan - •
/speckit.tasks- Regenerate tasks - •
/speckit.analyze- Verify consistency
- •
CRITICAL: Never manually edit plan.md or tasks.md. Always regenerate via /speckit. commands after spec changes.*
1. Detect Mismatches
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:
- •Missing in code: Spec requires it, code doesn't have it
- •Extra in code: Code implements it, spec doesn't mention it
- •Different behavior: Spec says X, code does Y
- •Ambiguous spec: Spec unclear, code made assumption
Document all mismatches with:
- •Spec requirement (quote from spec)
- •Actual implementation (what code does)
- •Location (file:line in code, section in spec)
2. Analyze Each Mismatch
For each mismatch, determine:
Type:
- •Architectural (affects system design)
- •Behavioral (changes functionality)
- •Cosmetic (naming, organization, details)
Severity:
- •Critical: Breaking change, security issue, data loss
- •Major: Significant behavior change, API contract change
- •Minor: Small deviation, non-breaking addition
- •Trivial: Naming, formatting, implementation details
Impact:
- •User-facing vs internal
- •Breaking vs non-breaking
- •Risky vs safe
3. Recommend Resolution
For each mismatch, recommend:
Option A: Update Spec
- •When: Implementation reveals better approach
- •Why: Spec was incomplete/wrong, code is better
- •Impact: Spec changes to match reality
Option B: Fix Code
- •When: Code deviates from intended design
- •Why: Spec is correct, code is wrong
- •Impact: Code changes to match spec
Option C: Clarify Spec
- •When: Spec was ambiguous, code made reasonable choice
- •Why: Make implicit explicit
- •Impact: Spec expanded with details, code unchanged
Provide reasoning for recommendation:
- •Why this option is best
- •Trade-offs of alternatives
- •Risk assessment
- •User impact
4. Decide Resolution
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:
{
"sdd": {
"auto_update_spec": {
"enabled": true,
"threshold": "minor", // "none", "minor", "moderate"
"notify": true
}
}
}
Thresholds:
- •
none: Never auto-update - •
minor: Auto-update trivial/minor mismatches - •
moderate: Include non-breaking behavioral changes
5. Execute Resolution
Option A: Update Spec
- •Modify spec to match implementation
- •Add to spec changelog
- •Validate updated spec for soundness
- •Commit spec change with clear message
# 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
- •Modify code to match spec
- •Update tests if needed
- •Verify spec compliance
- •Commit code change
# Fix code [Make changes to match spec] # Update tests [Adjust tests to match spec] # Verify compliance [Run sdd: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
- •Add detail to spec (keep code unchanged)
- •Make implicit assumptions explicit
- •Add to spec changelog
- •Commit clarification
Option D: Defer
- •Document as known deviation
- •Add to spec's "Known Deviations" section
- •Note reason and plan to address
- •Commit documentation
6. Verify Reconciliation
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:
- •Spec and code now aligned
- •Tests still passing
- •No regressions introduced
- •All spec-kit artifacts regenerated and in sync
Checklist
Use TodoWrite to track:
- • Detect all spec/code mismatches
- • Categorize each mismatch (type, severity, impact)
- • Analyze and recommend resolution for each
- • Check user configuration for auto-update
- • Decide resolution (auto or ask user)
- • Execute resolution (update spec, fix code, or clarify)
- • Verify reconciliation complete
- • Commit changes with clear messages
- • Update documentation if needed
Examples
Example 1: Auto-Update (Minor Addition)
[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)
Example 2: User Decision (Major Change)
[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 ✅
Example 3: Fix Code (Spec Correct)
[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
}
}
Classification Guidelines
Minor (Auto-Update Eligible)
- •Adding timestamps to responses
- •Renaming variables/functions
- •Reorganizing code structure
- •Adding logging/instrumentation
- •Implementation detail changes
Major (Always Ask)
- •Changing API contracts
- •Modifying behavior
- •Adding/removing features
- •Changing error handling
- •Architectural changes
Critical (Usually Fix Code)
- •Security issues
- •Data integrity problems
- •Missing required features
- •Incorrect business logic
Common Patterns
Pattern: Better Error Messages
Mismatch: Spec says "return error", code returns detailed error with context
Resolution: Update spec (minor)
- •More detailed errors are better
- •Non-breaking improvement
Pattern: Missing Edge Case
Mismatch: Spec doesn't mention empty array, code handles it
Resolution: Clarify spec (add edge case)
- •Make implicit explicit
- •Document intended behavior
Pattern: Performance Optimization
Mismatch: Spec doesn't specify caching, code adds cache
Resolution: Update spec (moderate)
- •Document optimization in spec
- •Ensure cache behavior is correct
Pattern: Different Architecture
Mismatch: Spec implies synchronous, code is async
Resolution: Ask user (major)
- •Significant architectural change
- •May affect other components
Remember
Spec evolution is normal and healthy.
- •Specs are not contracts set in stone
- •Implementation reveals reality
- •Better approaches emerge during coding
- •Ambiguities get discovered
The goal is alignment, not rigidity.
- •Specs guide implementation
- •Implementation informs specs
- •Both should reflect truth
Always provide reasoning:
- •Why update spec vs fix code
- •What's the impact
- •What are the trade-offs
Trust the process:
- •Detect mismatches early
- •Analyze thoughtfully
- •Recommend clearly
- •Execute decisively
- •Verify completely
Spec and code in sync = quality software.