Diagnose and fix a bug methodically, and track the investigation in the owning task. Use when something is broken, a test fails, behavior is wrong, or asked to "debug X", "fix this bug", "why is this failing". Reproduces, finds root cause, fixes minimally, verifies, and records it in tasks/TASK-<ID>/debug.md. Attaches to the spec → plan → coding → review workflow whenever a defect appears.
Scanned 8/31/2026
Install to Claude Code
npx -y skills add bonnguyenitc/specship --skill ss-debug --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ss Debug?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/bonnguyenitc-ss-debug)More formats (shields.io, HTML) on the badges page.
---
name: ss-debug
model: opus
description: Diagnose and fix a bug methodically, and track the investigation in the owning task. Use when something is broken, a test fails, behavior is wrong, or asked to "debug X", "fix this bug", "why is this failing". Reproduces, finds root cause, fixes minimally, verifies, and records it in tasks/TASK-<ID>/debug.md. Attaches to the spec → plan → coding → review workflow whenever a defect appears.
---
# Debug
Goal: find the **root cause** of a defect and fix it with the smallest correct change — never patch symptoms. Record the investigation so it's not lost.
## When to use
- A test fails, the app misbehaves, or a regression appears.
- Asked to "debug", "fix this bug", or "why is this failing".
- Can be triggered at any point in the workflow (during `coding`, during `review`, or on a bug found later).
## Shared task state
Part of the task pipeline — see `../WORKFLOW.md` for the full contract. `ss-debug` attaches to a task rather than being a fixed pipeline stage.
- **Hydrate:** resolve the owning `TASK-<ID>` (see "Attach the bug to a task" below), read its `task.md`, and `spec.md`/`plan.md` as needed. If no task owns it, create a new one.
- **Checkpoint:** append the `BUG#` entry to `debug.md`; update `task.md` — set `debug` artifact `open-bugs`/`clear`, set `status: blocked` while a blocker bug is open (note it in `Blocked by:`), bump `updated:`, append a Pipeline Log line carrying your agent label (format: `../WORKFLOW.md` → Agent handoff). Clear back to `active` when fixed and return to the stage you came from. (`blocked` is involuntary; see `../WORKFLOW.md` → Status values.)
- **Lessons:** read `tasks/LESSONS.md` at hydrate and apply its rules; if the bug's root cause was a process mistake (e.g. a skipped verify, a stale plan), fix the process trace too and append an `L#` entry there (see `../WORKFLOW.md` → Lessons).
## Attach the bug to a task
- **If the bug belongs to an existing task** (it's in code that task touched, or found during its `coding`/`review`): track it in that task's folder → `tasks/TASK-<ID>/debug.md`.
- **If it's a standalone bug with no task**: create a new `tasks/TASK-<ID>/` (from a ticket id, or generated per `../WORKFLOW.md` → "Choosing `TASK-<ID>`") and record it there. A `spec.md` is optional for a pure bugfix, but always keep the debug record.
- If unsure which task owns it, ask the user before picking.
## Method — scientific debugging
Work from evidence, one hypothesis at a time. Don't guess-and-change.
1. **Reproduce — no fix before a repro.** Get a reliable, minimal reproduction and **watch it fail for the expected reason** before touching any code; a fix you can't demonstrate failing is a guess. If you can't reproduce it, *that* is the investigation — add logging, tighten the conditions, gather evidence — don't "fix" what you can't observe. Capture the exact error/stack, inputs, and environment, and **write the failing test** that triggers the bug — it becomes the regression test. When `ss-coding` hands off after its 3-attempt rule, start from its failing `verify:` command as the repro and **read what was already tried** — those disproven attempts are evidence, not a path to retread.
2. **Locate** — narrow where it happens: read the stack trace, follow the data, add targeted logging or use the debugger, bisect if needed. Use `grep`/`rg` to trace the code path. For a deep, noisy investigation (large logs, many files), delegate the search to the **`ss-explorer`** agent if your platform can spawn it (it ships with specship for Claude Code), else **Explore** / `general-purpose`, and ask only for the suspected location + evidence — then do the fix and verification yourself in this thread. If your platform can't spawn subagents, do the same investigation **inline** in the main thread (`../WORKFLOW.md` → In-stage subagents — delegation is an optimization, never a precondition).
3. **Hypothesize — one at a time, revert what fails.** State the suspected root cause explicitly before changing anything, and confirm it with evidence (a log, a value, a failing assertion), don't assume. If the evidence disproves it, **revert that attempt's changes before testing the next hypothesis** — stacked speculative edits pollute the diff and can mask the symptom without fixing the cause. Record each ruled-out hypothesis (and what disproved it) in the `BUG#` entry so the investigation survives interruption and nobody retreads it.
4. **Fix** — apply the **minimum** change that addresses the root cause. Stay surgical; don't refactor unrelated code or fix symptoms downstream.
5. **Verify** — the failing test now passes, the full suite stays green, and the original reproduction is gone.
6. **Prevent regression — and sweep for siblings.** Keep the test that reproduces it. Then hunt the same bug class elsewhere: `grep`/`rg` for the pattern the root cause exposed (same misused API, same copy-pasted logic, same unchecked input). Trivially-same instances: fix in this `BUG#`. Bigger ones: record them in `related:` as explicit follow-ups — a root cause usually has siblings, and finding them now is far cheaper than a second debug session later.
If the root cause turns out to be a wrong/missing requirement, flag it back to `spec.md` (add an `R#`/edge case) rather than silently coding around it.
## Output: record the investigation in the task
Append the bug to **`tasks/TASK-<ID>/debug.md`** (create it if missing). Each bug is a `BUG#` entry — never renumber, only append — so it reads as a chronological debug log for the task.
```markdown
---
task: TASK-<ID>
title: <short title>
type: debug
created: <YYYY-MM-DD HH:MM +TZ>
updated: <YYYY-MM-DD HH:MM +TZ>
---
# Debug Log: TASK-<ID>
## BUG1 — <one-line summary>
- status: fixed # investigating | fixed | wont-fix
- date: <YYYY-MM-DD HH:MM +TZ>
- symptom: <observed wrong behavior + error/stack>
- reproduce: <steps / failing test that triggers it>
- ruled out: <hypotheses tried and disproven, with the evidence — omit if none>
- root cause: <the actual underlying cause, at `path` (`symbol`) — not a line number; they drift>
- fix: <what changed and why, files touched>
- regression test: <test name/path guarding it>
- related: <R#/AC#/S# affected, or other code with the same risk>
```
Update the entry's `status` as you go, and bump `updated:` on each change so the log tracks the fix over time.
## When done
- State plainly: reproduced? root cause found? fix verified with the full suite green?
- **Do not run `git add` / `commit` / `push`** unless the user asks.
## External phase execution
If an orchestrator launched you for the **`debug` phase only** (`../WORKFLOW.md` → External phase execution), the rules there override the handoff below. In short: confirm the envelope with `specship check TASK-<ID> --phase debug --actor <codex|claude-code> --expect-revision <n> --json` (exit 0 or stop), work from the named task's artifacts and the repro alone, write `debug.md` plus the regression test, then checkpoint `task.md` **last** with `revision` +1 and **stop**. Don't invoke the stage you interrupted, don't call `ss-ship` — skip "Next step" entirely.
**Carry the resume phase in the state, not in your head.** While bugs are open (`debug: open-bugs`), `resume_phase:` must name the phase debug interrupted — `coding` or `review`. When you clear the last blocker bug (`debug: clear`), set `next_phase:` back to that phase and **clear `resume_phase:`**. Both halves are checked: open bugs without a `resume_phase`, or a cleared debug that left one behind, fail the gate.
## Next step
The `BUG#` entry and its regression test are the input for whatever stage resumes.
- **Interrupted `coding` or `review`** — once the fix is verified, **ask the user whether to resume that stage** — e.g. "Bug đã fix xong, bạn có muốn tôi tiếp tục coding/review không?". If yes, **immediately invoke that skill** (via the Skill tool); it re-hydrates from `task.md` and picks up where it left off.
- **Standalone bugfix** (no interrupted stage) — suggest the `ss-review` skill to run the full gate and draft the commit message before handing off.
- If the user declines, stop here.
- Under `ss-ship` (autopilot), skip the question and resume the interrupted stage directly.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!