| allowed-tools | Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion, TodoWrite |
|---|---|
| description | Separate structural and behavioral changes following Beck's Tidy First |
| argument-hint | <description of desired change> |
You are guiding the user through Beck's "Tidy First" methodology, which requires separating structural changes from behavioral changes into distinct commits.
$ARGUMENTS
From .agent_instructions/code_style.md:
Never mix structural and behavioral changes in the same commit
- STRUCTURAL CHANGES: Rearranging code without changing behavior (renaming, extracting methods, moving code)
- BEHAVIORAL CHANGES: Adding or modifying actual functionality
This separation makes code reviews easier, reduces bugs, and creates clearer git history.
First, understand what the user wants to accomplish and identify the files involved.
Steps:
- Read the relevant code files to understand current state
- Analyze what needs to change to accomplish the goal
- Categorize changes into STRUCTURAL vs BEHAVIORAL
Use TodoWrite to track the changes you identify:
- Analyze current code (in_progress)
- Identify structural changes needed (pending)
- Identify behavioral changes needed (pending)
- Make structural changes (pending)
- Validate with tests (pending)
- Commit structural changes (pending)
- Make behavioral changes (pending)
- Validate with tests (pending)
- Commit behavioral changes (pending)
Categorization Guide:
STRUCTURAL (refactoring) - Does NOT change behavior:
- Renaming variables, methods, classes
- Extracting methods to reduce complexity
- Moving code to different files/classes
- Simplifying nested conditionals (same logic, clearer structure)
- Reducing indentation levels
- Breaking up large methods
- Replacing magic numbers with named constants
- Converting primitives to expressive types (if behavior identical)
BEHAVIORAL - DOES change functionality:
- Adding new features
- Changing algorithms or logic
- Modifying error handling
- Adding validation
- Changing I/O operations
- Adding caching
- Modifying retry logic
- Changing data transformations
Use AskUserQuestion to confirm your analysis:
Question: "I've analyzed the changes needed. Does this categorization look correct?"
Show the user:
STRUCTURAL changes (to be done first):
- [List structural changes you identified]
BEHAVIORAL changes (to be done after):
- [List behavioral changes you identified]
Options:
- "Yes, proceed with structural changes first" - Continue to Phase 3
- "Adjust the categorization" - User explains adjustments needed
- "Skip structural changes, do behavioral only" - Jump to Phase 5
If user adjusts, update your todo list and ask for confirmation again.
CRITICAL RULE: Do NOT change behavior in this phase. Only change structure.
Steps:
- Make the structural changes you identified
- Follow code style guidelines from .agent_instructions/code_style.md
- Update XML documentation if public API structure changed
- Do NOT add new functionality
- Do NOT change logic or algorithms
Code Style Guidelines to Apply:
- Keep methods small and focused (one level of indentation max)
- Use expressive names that reveal intention
- Extract methods to express intent instead of comments
- Avoid primitive obsession - use expressive types
- Follow .NET C# naming conventions
- Maintain documentation for public APIs
After making changes:
- Update your todo list (mark structural changes as completed)
- Show the user what you changed and why
CRITICAL STEP: Prove that structural changes didn't alter behavior.
Steps:
- Run the test suite to ensure all tests still pass
- If tests fail, you broke behavior - fix it immediately
- If tests pass, structural changes are validated
dotnet testIf tests fail:
- This means you accidentally changed behavior
- Revert the breaking change
- Fix it to be truly structural
- Run tests again until all pass
If tests pass:
- Update todo list (mark validation as completed)
- Proceed to commit
Only commit if all tests pass.
Commit Message Format:
refactor: [brief description of structural changes]
[Optional: More detailed explanation of what was refactored and why]
Examples:
refactor: extract method to simplify message processing logicrefactor: rename variables for clarity in KafkaConsumerrefactor: reduce nesting in error handling code
Steps:
- Stage the structural changes:
git add [files] - Create commit with message above
- Update todo list (mark commit as completed)
- Inform user structural phase is complete
Ask user: "Structural changes committed. Should I proceed with behavioral changes?"
Options:
- "Yes" - Continue to Phase 6
- "No, stop here" - End workflow
- "Review the changes first" - Pause for user review
Now you can change behavior.
Steps:
- Make the behavioral changes you identified in Phase 1
- Follow code style and documentation guidelines
- Add proper error handling
- Update or add XML documentation for new/changed public APIs; no comments inside method bodies (documentation.md § Comments in Code)
- Follow test-first if adding new behavior (consider using
/test-firstfor this)
If adding significant new behavior:
- Suggest using
/test-firstcommand instead - Tidy First is best for changes with both refactoring and behavior modifications
- Pure feature additions work better with TDD workflow
After making changes:
- Update todo list (mark behavioral changes as completed)
- Show user what you changed
Run the full test suite again:
dotnet testIf tests fail:
- Fix the failures
- These are legitimate behavior changes, so failures might be expected
- If you're adding new behavior, you might need to write new tests first
If tests pass:
- Update todo list (mark validation as completed)
- Proceed to commit
Only commit if tests pass (or new tests are added for new behavior).
Commit Message Format:
[type]: [brief description of behavioral change]
[Optional: More detailed explanation]
Commit Types:
feat:- New featurefix:- Bug fixperf:- Performance improvementrefactor:- If you ended up with only structural changes
Examples:
feat: add exponential backoff to retry logicfix: correct offset acknowledgment in Kafka consumerperf: implement caching for message deserialization
Steps:
- Stage the behavioral changes:
git add [files] - Create commit with message above
- Update todo list (mark all remaining as completed)
- Inform user that workflow is complete
Show the user:
- Summary of both commits created
- Offer to push to remote if on a feature branch
- Suggest next steps (create PR, continue with more changes, etc.)
Good fit:
- You need to refactor code AND add/change functionality
- Existing code is hard to understand/modify
- Changes touch multiple areas requiring cleanup
- Large methods need breaking down before adding features
Not a good fit:
- Pure refactoring (no behavioral changes planned)
- Pure feature addition (use
/test-firstinstead) - Trivial changes that don't need structural cleanup
What if no structural changes are needed?
- Skip to behavioral changes
- Still separate into clean commits
- Consider if any "while you're here" improvements would help
What if no behavioral changes are needed?
- This is pure refactoring
- Make changes, validate with tests, commit as
refactor: - No need for second commit
What if tests don't exist?
- Warn user that you cannot validate structural changes didn't break behavior
- Suggest writing tests first
- Proceed with caution if user approves
What if structural changes require interface changes?
- If public API must change structurally, include in structural commit
- Document clearly why API changed
- Update all call sites in same commit to keep things working
User: /tidy-first optimize the message processing in KafkaConsumer
[Claude reads KafkaConsumer.cs and analyzes]
I've analyzed the changes needed for optimizing message processing:
STRUCTURAL changes (to be done first):
- Extract nested conditional logic into IsValidMessage() method
- Rename 'msg' variable to 'message' for clarity
- Reduce indentation in ProcessBatch method
- Move magic number 1000 to constant MAX_BATCH_SIZE
BEHAVIORAL changes (to be done after):
- Add caching for deserialized messages
- Implement early exit for empty batches
- Change retry backoff from linear to exponential
Does this categorization look correct?
> Yes, proceed
🔧 STRUCTURAL: Making refactoring changes...
[Shows code changes]
- Extracted IsValidMessage() method
- Renamed variables
- Reduced nesting
- Added constant
Running tests to validate no behavior changed...
✓ All 47 tests pass - no behavior changed
Committing structural changes...
✓ Committed: refactor: simplify message processing structure in KafkaConsumer
Should I proceed with behavioral changes?
> Yes
✨ BEHAVIORAL: Adding caching and optimizations...
[Shows code changes]
- Added message cache using MemoryCache
- Early exit for empty batches
- Exponential backoff implementation
Running tests...
✓ All 47 tests pass
Committing behavioral changes...
✓ Committed: feat: add caching and exponential backoff to message processing
Complete! Two commits created:
1. refactor: simplify message processing structure in KafkaConsumer
2. feat: add caching and exponential backoff to message processing
This separation makes code review easier and git history clearer.
From .agent_instructions/code_style.md:
- Easier Code Review: Reviewers can approve structural changes quickly, focus on behavioral logic
- Clearer Git History: Each commit has single purpose (structure OR behavior)
- Safer Refactoring: Tests validate structural changes didn't break anything
- Better Debugging: If behavioral change causes bug, structural changes aren't suspected
- Disciplined Development: Forces thinking about "how code looks" vs "what code does"
/test-first- Use for pure feature addition with TDD/spec:implement- Uses TDD workflow, could benefit from tidy-first approach/commit- Standard commit workflow (doesn't separate structural/behavioral)