Guides
Reverse ACDD

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:

  1. Analyze your project - Detect gaps (missing features, tests, or coverage)
  2. Suggest a strategy - Choose from 4 reverse ACDD strategies (A, B, C, D)
  3. Guide step-by-step - Provide detailed instructions for each file/scenario
  4. Track progress - Maintain session state as you work
  5. 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:

  1. Document what's clear from the code
  2. Mark scenarios as "AMBIGUOUS" with comments
  3. 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:

See Also