Reverse ACDD
Reverse engineer existing codebases to create specifications.
What is Reverse ACDD?
Reverse ACDD is a technique for reverse engineering existing codebases without specifications to discover user stories, personas, and acceptance criteria, then create fspec artifacts (work units, epics, feature files, test skeletons).
Use cases:
- Legacy codebases without specifications
- Projects transitioning to ACDD workflow
- Understanding inherited code through BDD lens
- Documenting existing functionality for AI agents
Quick Start
Interactive strategy planning with fspec reverse
# Let fspec analyze your project and suggest a strategy
fspec reverse
# Or run directly with `/rspec` in Claude Code:
/rspec
fspec will:
- Analyze your project - Detect gaps (missing features, tests, or coverage)
- Suggest a strategy - Choose from 4 reverse ACDD strategies (A, B, C, D)
- Guide step-by-step - Provide detailed instructions for each file/scenario
- Track progress - Maintain session state as you work
- Validate completion - Ensure all gaps are filled before finishing
The Four Reverse ACDD Strategies
fspec automatically detects your project state and suggests the best approach:
Strategy A: Spec Gap Filling
When: You have tests but no feature files Process: Tests → Feature files → Coverage links
fspec reverse --strategy=A
# AI reads existing tests and creates matching Gherkin scenarios
Example:
src/__tests__/auth.test.ts exists ✓
spec/features/user-authentication.feature missing ✗
→ Create feature file from test assertions
→ Link with: fspec link-coverage --skip-validation
Strategy B: Test Gap Filling
When: You have feature files but no tests Process: Features → Test skeletons → Coverage links
fspec reverse --strategy=B
# AI reads feature scenarios and creates skeleton test files
Example:
spec/features/user-authentication.feature exists ✓
src/__tests__/auth.test.ts missing ✗
→ Create test skeleton with TODO comments
→ Link with: fspec link-coverage --skip-validation
Strategy C: Coverage Mapping
When: You have both features and tests, but no coverage links Process: Link existing tests to scenarios
fspec reverse --strategy=C
# AI maps existing tests to feature scenarios
Example:
spec/features/user-authentication.feature exists ✓
src/__tests__/auth.test.ts exists ✓
Coverage mapping missing ✗
→ Link scenarios to tests: fspec link-coverage
Strategy D: Full Reverse ACDD
When: You have code but no features or tests Process: Code → Features → Tests → Work units
fspec reverse --strategy=D
# AI analyzes implementation and creates everything from scratch
Example:
src/routes/auth.ts exists ✓
No features, tests, or work units ✗
→ Analyze implementation
→ Create feature files
→ Create test skeletons
→ Create work units
→ Link coverage
Interactive Session Management
fspec tracks your reverse ACDD progress in a session file:
Starting a Session
# Initial analysis - fspec suggests a strategy
fspec reverse
# Choose strategy and start
fspec reverse --strategy=A
Working Through Steps
# Get current step instructions
fspec reverse --status
# Complete current step, move to next
fspec reverse --continue
Session Commands
# Check progress
fspec reverse --status
# Shows: "Step 2 of 5 | Strategy A | Files: auth.test.ts (current)"
# Preview without creating session
fspec reverse --dry-run
# Abandon current session
fspec reverse --reset
# Mark session complete
fspec reverse --complete
Decision Tree
fspec uses this logic to suggest strategies:
Example Workflow
Strategy A: Creating Features from Tests
# 1. Analyze project
$ fspec reverse
✓ Detected: 3 test files without feature files
✓ Suggested: Strategy A (Spec Gap Filling)
# 2. Start Strategy A
$ fspec reverse --strategy=A
✓ Session created
→ Step 1 of 3: src/__tests__/auth.test.ts
# 3. Read test file
$ cat src/__tests__/auth.test.ts
# Contains: "should login with valid credentials"
# 4. Create feature file
$ fspec create-feature "User Authentication"
$ fspec add-scenario user-authentication "Login with valid credentials"
# 5. Link coverage (skip validation for skeleton)
$ fspec link-coverage user-authentication \
--scenario "Login with valid credentials" \
--test-file src/__tests__/auth.test.ts --test-lines 10-25 \
--skip-validation
# 6. Move to next step
$ fspec reverse --continue
→ Step 2 of 3: src/__tests__/profile.test.ts
# 7. Repeat for remaining files...
# 8. Complete session
$ fspec reverse --complete
✓ All gaps filled
## How It Works
### 1. Analyze Codebase
The AI identifies user-facing interactions based on your application type:
**Web apps:**
- Routes (GET /login, POST /checkout)
- API endpoints
- UI components and pages
**CLI apps:**
- Commands and subcommands
- Flags and options
- Input/output patterns
**Desktop/Mobile apps:**
- Screens and views
- Actions and gestures
- Navigation flows
**Services:**
- Scheduled jobs
- Event processors
- Message handlers
### 2. Group into Epics
Organize features by business domain:
```bash
fspec create-epic "User Management" AUTH "Authentication and sessions"
fspec create-epic "Payment Processing" PAY "Checkout and payments"
fspec create-epic "Admin Dashboard" ADMIN "Admin features"
3. Create Work Units
One work unit per user story:
fspec create-work-unit AUTH "User Login" --epic=user-management
fspec update-work-unit-status AUTH-001 specifying
4. Generate Feature Files
Infer acceptance criteria from code:
-
Routes → Scenarios
POST /login
→ "Login with valid credentials" -
Error handling → Edge cases 401 error → "Login with invalid credentials"
-
Validation → Preconditions
email.includes('@')
→ valid email format required -
Business logic → Rules
age >= 18
→ user must be adult
Example generated feature file:
@phase1 @authentication @api
Feature: User Login
Background: User Story
As a registered user
I want to log in to my account
So that I can access my personalized dashboard
Scenario: Login with valid credentials
Given I have a registered account
And I am on the login page
When I enter my email and password
And I click the "Login" button
Then I should be redirected to my dashboard
And I should see a welcome message
Scenario: Login with invalid credentials
Given I am on the login page
When I enter an invalid email or password
And I click the "Login" button
Then I should see an error message
And I should remain on the login page
5. Create Test Skeletons
Generate test structure (NOT implemented):
/**
* Feature: spec/features/user-login.feature
*
* NOTE: This is a skeleton test file generated by reverse ACDD.
* Tests are NOT implemented - only structure is provided.
*/
describe('Feature: User Login', () => {
describe('Scenario: Login with valid credentials', () => {
it('should redirect to dashboard', async () => {
// TODO: Implement this test
// Map: src/routes/auth.ts:45-67
});
it('should show welcome message', async () => {
// TODO: Implement this test
// Map: src/components/Dashboard.tsx:23-30
});
});
describe('Scenario: Login with invalid credentials', () => {
it('should show error message', async () => {
// TODO: Implement this test
// Map: src/routes/auth.ts:72-78
});
});
});
6. Link Coverage
Map scenarios to existing code:
# Link skeleton test (use --skip-validation for unimplemented tests)
fspec link-coverage user-login --scenario "Login with valid credentials" \
--test-file src/__tests__/auth-login.test.ts --test-lines 13-27 \
--skip-validation
# Link existing implementation
fspec link-coverage user-login --scenario "Login with valid credentials" \
--test-file src/__tests__/auth-login.test.ts \
--impl-file src/routes/auth.ts --impl-lines 45-67 \
--skip-validation
7. Update Foundation
Add user story maps to foundation documentation:
fspec add-diagram "User Story Maps" "Auth Flow" "
graph TB
User[User] -->|Login| AUTH-001[User Login]
AUTH-001 -->|Success| DASH-001[View Dashboard]
AUTH-001 -->|Failure| AUTH-002[Password Reset]
"
Handling Ambiguous Code
When encountering unclear business logic, the AI will:
- Document what's clear from the code
- Mark scenarios as "AMBIGUOUS" with comments
- Offer Example Mapping to clarify with human
# AMBIGUOUS: magic number 42 in discount logic - needs human clarification
Scenario: Apply special discount
Given a customer has a discount code
And the discount value is greater than 42 # Why 42? Ask human.
When they complete checkout
Then a special discount should be applied
Resolution:
# Add question to work unit
fspec add-question PAY-003 "Why is 42 the threshold for special discounts?"
# Human answers
fspec answer-question PAY-003 0 \
--answer "Customers with 42+ loyalty points get VIP discount" \
--add-to rule
Completion Criteria
Reverse ACDD is complete when:
- ✅ All user-facing interactions have feature files
- ✅ All epics have at least one work unit
- ✅ foundation.json contains user story map(s)
- ✅ All ambiguous scenarios documented
- ✅ Skeleton test files exist with coverage mappings
- ✅ Project can be queried with
fspec board
,fspec list-features
, etc.
Transitioning to Forward ACDD
After reverse ACDD, use forward ACDD for new features:
# New feature: Two-factor authentication
fspec create-work-unit AUTH "Two-factor authentication" --epic=user-management
fspec update-work-unit-status AUTH-010 specifying
# Start with Example Mapping (not reverse engineering)
fspec add-rule AUTH-010 "Users can enable 2FA via SMS or authenticator app"
fspec add-example AUTH-010 "User enables 2FA, receives SMS code on next login"
fspec add-question AUTH-010 "Should 2FA be required or optional?"
# Generate scenarios from discovery
fspec generate-scenarios AUTH-010
# Write tests BEFORE code (forward ACDD)
# ...tests fail (red phase)
fspec update-work-unit-status AUTH-010 testing
fspec update-work-unit-status AUTH-010 implementing
# ...write code to make tests pass (green phase)
Best Practices
DO
- ✅ Start with high-level user journeys
- ✅ Group related routes/screens into single work units
- ✅ Use
--skip-validation
when linking skeleton tests - ✅ Document ambiguities with comments
- ✅ Create Example Maps for unclear requirements
- ✅ Link coverage as you discover it
DON'T
- ❌ Try to reverse engineer everything at once
- ❌ Skip linking coverage (you lose traceability)
- ❌ Write new tests before documenting existing code
- ❌ Guess at unclear business logic (mark as AMBIGUOUS)
- ❌ Create work units for implementation details
Example: Reverse Engineering Express API
# 1. Analyze routes
/rspec Analyze all routes in src/routes/
# AI discovers:
# - POST /api/users/login (AUTH-001)
# - GET /api/users/profile (PROFILE-001)
# - POST /api/payments/checkout (PAY-001)
# 2. Creates epics
fspec create-epic "Authentication" AUTH "User auth and sessions"
fspec create-epic "User Profiles" PROFILE "User profile management"
fspec create-epic "Payments" PAY "Payment processing"
# 3. Creates work units
fspec create-work-unit AUTH "User login via API" --epic=authentication
fspec create-work-unit PROFILE "View user profile" --epic=user-profiles
fspec create-work-unit PAY "Checkout flow" --epic=payments
# 4. Generates feature files
spec/features/user-login-api.feature
spec/features/view-user-profile.feature
spec/features/checkout-flow.feature
# 5. Creates test skeletons
src/__tests__/auth-login.test.ts
src/__tests__/profile-view.test.ts
src/__tests__/checkout.test.ts
# 6. Links coverage
fspec link-coverage user-login-api --scenario "Login with valid credentials" \
--test-file src/__tests__/auth-login.test.ts --test-lines 10-25 \
--impl-file src/routes/auth.ts --impl-lines 45-67 \
--skip-validation
# 7. Check coverage
fspec show-coverage
# Output shows which scenarios are mapped to code
Commands Reference
See the full command reference for details:
- Specification Commands - Create and manage feature files
- Work Management - Create and manage work units
- Discovery Commands - Example Mapping for ambiguous scenarios
See Also
- Claude Code Integration - Installing the
/rspec
command - ACDD Concepts - Understanding forward ACDD workflow
- Coverage Tracking - Linking scenarios to code