Debug

SkillDev tools

Use on any bug, test failure, or unexpected behavior before proposing a fix. Enforces four-phase root-cause investigation — reproduce, pattern-match, hypothesize, fix — with a hard rule against symptom patches.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Debug skill

What this skill tells your AI

The instructions your AI receives, as published by btseytlin/ultrapack in skills/udebug/SKILL.md and read by ahel’s review.

Iron law: no fixes without root-cause investigation first. Symptom patches are failure.

When to invoke

Any technical issue: test failure, production bug, unexpected behavior, performance regression, build break, integration failure. Especially when:

  • Under time pressure (makes guessing tempting)
  • You already tried 1+ fixes
  • The problem "seems simple" (simple-looking bugs still have root causes)

Phase 1 — Reproduce the problem and trace the data

You cannot fix what you cannot observe. Start by making the bug happen on demand, then follow the bad value back to where it came from.

Phase 2 — Pattern analysis against a working example

Bugs rarely occur in isolation. Find similar code that works, understand why it works, then enumerate every difference.

Phase 3 — Single hypothesis, minimal test

One cause at a time. Stacked guesses turn fixes into guesses about guesses.

Phase 4 — Implement one fix, verify, stop at three failed attempts

Now and only now do you change production code.

Condition-based waiting — never use sleep(N) for timing bugs

A sleep that "seems long enough" is a bomb on a fuse. Poll for the actual condition with a bounded timeout:

deadline = time.time() + timeout
while time.time() < deadline:
    if condition():
        break
    time.sleep(0.1)
else:
    raise TimeoutError(f"condition not met in {timeout}s")

Defense in depth — validate one or two layers past the fix

Once the root cause is fixed, add validation at the next layer so the same class of bug can't re-enter silently:

  • Validate inputs at component boundaries
  • Crash loudly on contract violations
  • Log state transitions in long-running processes

Don't scatter defensive code everywhere. One or two layers past the fix is enough.

Anti-whack-a-mole — find the pattern before closing

One bug is rarely alone. Before marking the fix done, name the pattern behind it in one sentence and grep the rest of the code for the same shape. Report matches: fix the trivial ones in the same commit, file follow-ups for the rest. Closing without this check is how the same bug ships three more times in three more places.

Red flags — STOP, return to Phase 1

When root cause really is environmental

After systematic investigation, if the issue is timing, external, or truly non-deterministic:

  • Document what you investigated
  • Implement appropriate handling (retry, timeout with condition polling, loud error)
  • Add logging / monitoring for future occurrences

But most "no root cause" verdicts are incomplete investigations. Double-check before settling for this.

Terminal state

Fix verified with reproduction → return to up:uverify if in a task workflow, or commit and move on.

Signals

GitHub stars
47
Forks
12
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
udebug
Source
github.com/btseytlin/ultrapack