Debug

Reach for Debug the moment a fix did not work and you feel the pull to try it again with slightly different inputs.

The circuit breaker is not optional. Three failed hypotheses means stop, write the handoff and re-plan.

Most bugs that survive a fix do not survive because the fix was typed badly. They survive because something the person fixing them believes about the system is false. Each retry then tests how well that belief was carried out, and never checks the belief itself. Debug is built around that failure. It finds the cause before anything changes, and it stops after three failed guesses.

Two Rules

  1. No fix without a written hypothesis. Write the guess, and the output that would confirm it or kill it, before anything changes. "I'll just try this" is the sentence this rule refuses. One untracked change becomes ten, and then nobody knows which one mattered, or whether the bug will come back.

  2. Three failed hypotheses, then stop. After the third guess, the attempts end, a handoff is written, and the plan is rebuilt. A fourth guess tests the same belief again with new inputs. Setting the three attempts side by side makes the shared assumption visible, which a fourth untracked try never does.

Five Kinds Of Bug

Every session names its bug class on the first line, because the class decides the first action, and the first action decides which evidence will count.

Bug Class First Action
Regression Protect uncommitted work, then write one command that answers yes or no for the symptom
New Bug Write the hypothesis card before any change
Visual or Rendering Take a full-size screenshot before reading any log
Behavioral or Lifecycle Log what enters and leaves each step, before the step that fails
Timing Gather run counts and timestamps before any hypothesis

A visual bug proven by a log line has not been proven, and a timing bug fixed on one run has not been checked. Each first action is picked so that its evidence can decide the question for that class.

The Handoff

When the breaker trips, Debug writes a short file. It holds the problem in one line, every hypothesis marked eliminated or open with its evidence, what the evidence now points to, and one next action, such as a line to log at a named place. Later runs append to the file and never trim it, because a dead end removed from the record gets walked again. The problem line holds only what was observed. Beliefs go on their own line, marked as beliefs.

How A Fix Gets Reported

A fixed bug ends with an outcome block. It names the root cause at a file and a line, the fix at a file and a line, and the test that guards the fix. It also carries the red run from before the change, the green run after it, and the reproduction output with its exit code. For code, the failing test is written first and must be seen to fail. Every run is pasted from the session that makes the claim, because a passing run from last week only proves last week's code. Verify then grades the block, and a root cause with no failing test behind it is still only a claim.

Staying On One Symptom

Debug changes one thing, at one file and line, and leaves nearby problems alone. A second symptom noticed during the work goes on the list as an open thread for the owner, because a second fix in the same change makes the first fix impossible to prove. When two changes would both cure the proven cause, Debug names both, states what each one costs, and asks which one the owner wants. The owner can stop the session at any point, and that stop is written as a handoff with the state as it stands.