Chapter 8: Stable Mode
Stable mode answers a different question: does it handle reality? Reality includes invalid inputs, network failures, missing data, and users who do unexpected things. Stable mode adds the error handling and edge case coverage that makes software reliable. By now your feature works. Users can log in successfully with valid credentials. They can upload files that meet the requirements. They can complete the workflows you designed. But what happens when things go wrong?
Building on Speed Mode
Stable mode doesn't replace what you built in speed mode. It adds to it.
Your success scenarios still pass. Your core functionality still works. You're wrapping that working code with protection: validation before processing, error handling when things fail, edge case coverage for unusual situations.
Think of it like weatherproofing a house. The house is built. The rooms are there. Now you're adding insulation, sealing gaps, preparing it to handle harsh conditions.
The Five Dimensions of Stability
Stable mode addresses five concerns:
Error handling. Network requests fail. Databases go down. External services return errors. Stable mode adds try-catch blocks, error messages, and graceful degradation. When something fails, users see a helpful message instead of a crash.
Input validation. Users enter invalid email addresses. They submit empty forms. They paste text into number fields. Stable mode validates inputs before processing them and provides clear feedback when validation fails.
Edge cases. What happens with an empty list? With exactly one item? With the maximum allowed items? With special characters in the input? Edge cases are the boundary conditions that often get overlooked. Stable mode handles them explicitly.
State consistency. What happens if the process fails halfway through? If a user submits twice? If two users edit the same thing simultaneously? Stable mode ensures data stays consistent even when things go wrong.
Comprehensive test coverage. Speed mode tested success paths. Stable mode adds tests for all the failure paths. By the end, your test suite covers both what should work and what should fail gracefully.
The Same Loop, Different Focus
Stable mode follows the same RED-GREEN loop as speed mode. You have scenarios. They fail. You implement code. They pass.
The difference is what you're implementing. In speed mode, you built features. In stable mode, you're adding resilience to those features. The code you wrote in speed mode doesn't change much. You're wrapping it with validation, catching its errors, and handling its edge cases.
Run the new stable mode scenarios. They fail because the error handling doesn't exist yet. Add the error handling. Run again. Repeat until green.
What Stable Mode Looks Like
Here's a speed mode scenario:
Scenario: User successfully logs in with valid credentials
Given I am on the login page
When I enter valid email and password
And I click the login button
Then I am redirected to the dashboard
Here are stable mode scenarios for the same feature:
Scenario: Login fails with invalid credentials
Given I am on the login page
When I enter an invalid email and password combination
And I click the login button
Then I see an error message "Invalid email or password"
And I remain on the login page
Scenario: Login handles empty email
Given I am on the login page
When I leave the email field empty
And I click the login button
Then I see a validation error "Email is required"
Scenario: Login handles server error gracefully
Given I am on the login page
And the authentication service is unavailable
When I enter valid email and password
And I click the login button
Then I see an error message "Unable to log in. Please try again later."
The success scenario still works. You're adding scenarios for all the ways things can go wrong.
Working Through Stable Mode Chores
Each stable mode chore addresses a cluster of related scenarios. You might have:
Validation chore: Add input validation for email format, required fields, password requirements
Error handling chore: Handle authentication failures, network errors, service unavailability
Edge case chore: Handle empty inputs, special characters, boundary values
Work through them the same way you worked through speed mode chores. Create a worktree. Implement until scenarios pass. Merge. Cleanup. Start the next one.
When Stable Mode Ends
Stable mode ends when all stable mode scenarios pass. Every error condition is handled. Every validation is in place. Every edge case is covered.
What happens next depends on your project's state.
Internal projects stop here. Stable mode is the finish line. Your software works, handles errors gracefully, and won't corrupt data. That's sufficient for internal use. Mark the feature as done.
External projects continue to production mode. You're preparing to serve real users at scale. That requires additional hardening that stable mode doesn't address.