Legacy Code Symptom Router
by @quochungto
Diagnose any legacy-code situation in plain language and route to the right technique. Use as the FIRST skill when a developer has a vague or specific compla...
Example A: "My class won't instantiate in the test" β Test Harness Diagnostics
Developer input: "I'm trying to write a unit test for InvoiceCalculator. When I try to instantiate it in my test, I get a compile error because the constructor requires a live DatabaseConnection object. I can't create one of those in tests."
Classification: Symptom 4 β "I Can't Get This Class into a Test Harness" (Ch 9). Root cause: testability obstacle β constructor has a hard dependency on a concrete class.
Recommendation: Run test-harness-entry-diagnostics. It will walk through the 7-case triage from Chapter 9. In this case the pattern is "Irritating Parameter" (constructor requires a hard-to-create object) β the solution is either Extract Interface on DatabaseConnection and Parameterize Constructor, or pass null if InvoiceCalculator has logic to check for it.
Triage entry:
Symptom: Constructor requires a live DatabaseConnection
Chapter: Ch 9 β I Can't Get This Class into a Test Harness
Root cause: testability β class-level obstacle
Recommended skill: test-harness-entry-diagnostics
Fallback: Apply Parameterize Constructor manually (pass a DatabaseConnection interface instead of creating it in the constructor)
Example B: "500-line method I can't write tests for" β Monster Method Decomposition
Developer input: "We have a processOrder() method that's 600 lines. It handles everything: validation, pricing, inventory, notifications. I can't test it because it's too big β I don't know what inputs to use or what assertions to write. And it's tangled β calls methods all over the class."
Classification: Symptom 17 β "I Need to Change a Monster Method and I Can't Write Tests for It" (Ch 22). Root cause: design β method too large to test.
Recommendation: Run monster-method-decomposition. First classify the method type: is it Bulleted (sequential chunks with low indentation between logical sections) or Snarled (dominated by one deeply nested block)? From the description, this sounds Bulleted (validation, then pricing, then inventory, then notifications = sequential chunks). The strategy is Find Sequences: identify the overarching sequence of operations, then extract each operation to a named method, working from smallest chunks outward. Use automated refactoring only β no manual copy-paste.
Triage entry:
Symptom: 600-line processOrder() method, too complex to test
Chapter: Ch 22 β I Need to Change a Monster Method
Root cause: design β method too large, no seam to test individual operations
Recommended skill: monster-method-decomposition
Fallback: Classify as Bulleted or Snarled, then extract the smallest identifiable chunk first using automated Extract Method
Example C: "Our builds take 40 seconds, changes are painful" β Dependency Breaking for Build Speed
Developer input: "Any time we change a file in our core library, we have to recompile everything. A 40-second wait every change. It's killing our velocity. We don't know which parts of the build depend on which others."
Classification: Symptom 2 β "It Takes Forever to Make a Change" (Ch 7), specifically the build lag variant (not comprehension lag β they know what to change, they're just waiting for builds).
Diagnostic question asked: "Are you spending time figuring out WHAT to change, or waiting for the build after you've already changed it?" Developer said: "I know exactly what to change β I'm just waiting for the build."
Recommendation: Run dependency-breaking-technique-executor targeting the inter-module dependency structure. The goal is to break compilation dependencies between the core library and its consumers so a change to one area does not force recompilation of everything. Feathers' target: isolated class/module compilation + test run in under 10 seconds. Technique likely needed: Extract Interface to decouple consumers from the concrete class, allowing separate compilation.
Triage entry:
Symptom: 40-second builds on every change to core library
Chapter: Ch 7 β It Takes Forever to Make a Change (build lag variant)
Root cause: build lag β architecture creates excessive recompilation fan-out
Recommended skill: dependency-breaking-technique-executor
Fallback: Identify which concrete class is included by everything; introduce an interface for it so consumers compile against the interface, not the implementation
[Any skills to run first, or "none"]
clawhub install bookforge-legacy-code-symptom-router