Systematic debug
Skill onfire7777/universal-ai-skills-library/skills/systematic-debug
Router-first AI skill system for Codex, Claude, Cursor, Hermes, Paperclip, OpenCode, and local AI stacks: search, preflight-route, and load 1,812 skills on demand without duplicating the corpus.
npx -y skills add onfire7777/universal-ai-skills-library --skill systematic-debugAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Systematic debugging techniques for unclear root causes. Use when a bug's origin is unknown, multiple hypotheses need testing, you need to narrow down a failing area, end-to-end tests fail but you can't tell where, or the user says "I don't know why this is broken". Includes test bombs (hypothesis elimination) and layered tests (pipeline stage isolation).
The file declares its own license as Unspecified. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
12.4 KB, ~2.9k tokens by cl100k_base, as published. Nobody here has run it
Choose Your Technique
| Technique | Use when | Finds |
|---|---|---|
| Test Bomb | Root cause is unclear, multiple suspects | Which component/area is broken |
| Layered Test | System has a pipeline, output is wrong but stage is unclear | Which pipeline stage is broken |
| Both together | Complex bug in a pipeline system | Test bomb narrows the component, layered test pinpoints the stage |
Test Bombs
What is a Test Bomb?
A test bomb is a systematic debugging technique. Instead of writing one big test or guessing at the root cause, you:
- List every hypothesis about what could be broken
- Write one small test per hypothesis — named
H1_,H2_,H3_, etc. - Run them all together — the pass/fail pattern reveals the failing area
- Add more hypotheses as you learn, narrowing the scope
Each test is independent, fast, and documents exactly what it's proving or disproving.
When to Use Test Bombs
- Root cause of a bug is unclear
- Multiple components could be at fault
- You need to systematically eliminate possibilities
- A fix attempt didn't work and you need to understand why
- The user says things like "I don't know why this is broken" or "it used to work"
Test Bomb Steps
- Identify the bug — understand the symptom
- List suspected causes — brainstorm every reasonable hypothesis (aim for 5-15)
- Group hypotheses by area — organize into logical sections
- Write one test per hypothesis — each with a clear name, doc comment, and assertion
- Run all tests — analyze the pass/fail pattern
- Add edge-case hypotheses — based on what you learned from the first run
- Fix the root cause — now that you know exactly what's broken
- Keep the tests — they become permanent regression coverage
Test Bomb Templates
C# (xUnit)
/// TEST BOMB: Systematic elimination of suspected causes for [BUG DESCRIPTION].
public class [BugName]TestBomb(ITestOutputHelper output)
{
private readonly ITestOutputHelper _output = output;
// --- Section 1: [Area Name] ---
/// H1: [describe what you're testing and what pass/fail means]
[Fact(Timeout = 10000)]
public async Task H1_FirstHypothesis()
{
// Arrange — minimal setup for this one hypothesis
// Act — trigger the specific behavior
// Assert — one clear assertion
_output.WriteLine($"H1 Result: {result}");
Assert.Equal(expected, actual);
}
/// H2: [describe what you're testing]
[Fact(Timeout = 10000)]
public async Task H2_SecondHypothesis()
{
// ...
}
// --- Section 2: [Next Area] ---
/// H3: [describe what you're testing]
[Fact(Timeout = 10000)]
public async Task H3_ThirdHypothesis()
{
// ...
}
}
TypeScript (vitest/jest)
// TEST BOMB: Systematic elimination of suspected causes for [BUG].
describe('[BugName] Test Bomb', () => {
// --- Section 1: [Area Name] ---
// H1: [describe hypothesis]
test('H1_FirstHypothesis', async () => {
// ...
expect(actual).toBe(expected);
});
// H2: [describe hypothesis]
test('H2_SecondHypothesis', async () => {
// ...
});
});
Python (pytest)
# TEST BOMB: Systematic elimination of suspected causes for [BUG].
class TestBugNameTestBomb:
"""Systematic elimination of suspected causes for [BUG]."""
def test_h1_first_hypothesis(self):
"""H1: [describe hypothesis]"""
# ...
assert actual == expected
def test_h2_second_hypothesis(self):
"""H2: [describe hypothesis]"""
# ...
Go
// TEST BOMB: Systematic elimination of suspected causes for [BUG].
func TestH1_FirstHypothesis(t *testing.T) {
// H1: [describe hypothesis]
// ...
if actual != expected {
t.Errorf("H1: got %v, want %v", actual, expected)
}
}
func TestH2_SecondHypothesis(t *testing.T) {
// H2: [describe hypothesis]
// ...
}
Running Test Bombs
# C# / .NET
dotnet test --filter "FullyQualifiedName~TestBomb"
# TypeScript
npx vitest run --grep "Test Bomb"
# Python
pytest -k "TestBomb" -v
# Go
go test -run "TestH[0-9]+" -v ./...
Reading Test Bomb Results
| Pattern | Meaning |
|---|---|
| All pass | Bug is elsewhere — expand your hypotheses |
| All fail | Fundamental setup issue — check H1 carefully |
| One section fails | Root cause is in that area |
| Scattered failures | Multiple issues, or a shared dependency is broken |
| H1 passes, H3 fails | The difference between H1 and H3 isolates the cause |
Layered Tests
What is a Layered Test?
A layered test isolates bugs in systems that process data through sequential stages. Instead of only testing the final output, you test each intermediate stage independently — so you know exactly where the pipeline breaks.
Input → Stage1 → Stage2 → Stage3 → Stage4 → Output
L0 L1 L2 L3 L4 L5
If L3 fails but L1 and L2 pass, the bug is in Stage3.
When to Use Layered Tests
- Bug shows up at runtime/output but the failing stage is unclear
- System has a pipeline architecture (compiler, parser, HTTP middleware, data pipeline, ETL, etc.)
- You need to inspect intermediate state between stages
- End-to-end tests fail but you can't tell where
Common Pipeline Types
Compiler / Interpreter
Source → Lexer → Parser → AST → Semantic Analysis → Code Gen → Output
L0 L1 L2 L3 L4 L5 L6
HTTP Request Pipeline
Request → Auth → Validation → Business Logic → Serialization → Response
L0 L1 L2 L3 L4 L5
Data Pipeline / ETL
Raw Data → Extract → Transform → Validate → Load → Query Result
L0 L1 L2 L3 L4 L5
ML Pipeline
Raw Data → Preprocessing → Feature Engineering → Model → Post-processing → Output
L0 L1 L2 L3 L4 L5
Build System
Source → Dependency Resolution → Compilation → Linking → Packaging → Artifact
L0 L1 L2 L3 L4 L5
Layered Test Steps
- Map the pipeline — identify every processing stage from input to output
- Label the layers — L0 (input), L1 (first stage), L2 (second stage), ... LN (final output)
- Write tests per layer — each test asserts the output of one specific stage
- Start from L1, work forward — find the first layer that fails
- Compare passing vs failing — run a passing and failing case side-by-side at the broken layer to see the exact difference
Layered Test Templates
C# (xUnit)
/// LAYERED TESTS: Isolate which pipeline stage causes [BUG].
///
/// L1: [First stage] - does it produce correct intermediate output?
/// L2: [Second stage] - does it transform correctly?
/// L3: [Third stage] - does it handle the edge case?
/// L4: [Final stage] - full end-to-end assertion
/// L5: Side-by-side comparison of passing vs failing case
public class [BugName]LayeredTest(ITestOutputHelper output)
{
// ================================================================
// LAYER 1: [First Stage Name]
// ================================================================
/// L1_A: [what you're checking at this stage]
[Fact(Timeout = 10000)]
public async Task L1_A_Description()
{
// Get the intermediate output after stage 1
// Assert its structure/content is correct
}
// ================================================================
// LAYER 2: [Second Stage Name]
// ================================================================
/// L2_A: [what you're checking at this stage]
[Fact(Timeout = 10000)]
public async Task L2_A_Description()
{
// Get the intermediate output after stage 2
// Assert its structure/content is correct
}
// ================================================================
// LAYER N: Side-by-side comparison
// ================================================================
/// LN: Compare passing vs failing case at the broken layer
[Fact(Timeout = 10000)]
public async Task LN_ComparePassingVsFailing()
{
output.WriteLine("=== PASSING CASE ===");
// Run the passing input through the pipeline, log intermediate state
output.WriteLine("=== FAILING CASE ===");
// Run the failing input through the pipeline, log intermediate state
output.WriteLine("Compare the traces above to see the difference!");
}
}
TypeScript (vitest/jest)
// LAYERED TESTS: Isolate which pipeline stage causes [BUG].
describe('[BugName] Layered Test', () => {
// --- Layer 1: [First Stage] ---
test('L1_A_Description', () => {
const intermediate = stage1(input);
expect(intermediate).toMatchObject(expected);
});
// --- Layer 2: [Second Stage] ---
test('L2_A_Description', () => {
const intermediate = stage2(stage1(input));
expect(intermediate).toMatchObject(expected);
});
// --- Comparison ---
test('LN_ComparePassingVsFailing', () => {
console.log('=== PASSING CASE ===');
const passing = runPipeline(passingInput);
console.log(JSON.stringify(passing, null, 2));
console.log('=== FAILING CASE ===');
const failing = runPipeline(failingInput);
console.log(JSON.stringify(failing, null, 2));
});
});
Python (pytest)
# LAYERED TESTS: Isolate which pipeline stage causes [BUG].
class TestBugNameLayered:
"""Isolate which pipeline stage causes [BUG]."""
# --- Layer 1: [First Stage] ---
def test_l1_a_description(self):
"""L1_A: [what you're checking]"""
intermediate = stage1(input_data)
assert intermediate == expected
# --- Layer 2: [Second Stage] ---
def test_l2_a_description(self):
"""L2_A: [what you're checking]"""
intermediate = stage2(stage1(input_data))
assert intermediate == expected
Reading Layered Test Results
| Pattern | Meaning |
|---|---|
| All layers pass | Bug is in integration between stages, not individual stages |
| L1 fails | Problem is at the first stage — likely input parsing |
| L1-L2 pass, L3 fails | Bug is in stage 3 — inspect L2 output going into L3 |
| Only last layer fails | All stages work individually — check final assembly |
| Intermittent failures | Likely state leaking between stages or timing issue |
Combining Both Techniques
Workflow
- Run a test bomb to narrow down which component is at fault
- Run a layered test on that component to find the exact failing stage
- Fix the bug at the identified stage
- Keep both test classes as permanent regression coverage
Guidelines
Test bombs:
- Name hypotheses clearly:
H1_CatchBlockReturnsUndefinednotH1_Test - Add a doc comment to each test explaining the hypothesis
- Group related hypotheses into sections with comments
- Use timeouts to catch hangs (especially in async code)
- Log intermediate values — they help when analyzing failures
- Keep each test minimal — test ONE thing per hypothesis
- Start broad (5-8 hypotheses), then add targeted ones based on results
- Never delete passing tests — they prove areas are NOT broken
Layered tests:
- Always map the full pipeline before writing tests — missing a layer means missing a potential failure point
- Test each layer in isolation — don't let later stages mask earlier failures
- Log intermediate state at each layer — the comparison between passing and failing cases is the key diagnostic
- Include a side-by-side comparison test (passing vs failing input at the broken layer)
- Name tests with layer prefix:
L1_A_,L2_A_, etc. — makes the progression obvious - Start from L1 and work forward — find the first layer that fails
- Keep the tests after fixing — they're permanent regression coverage for each pipeline stage