Best for
- Use when the user asks to find bugs, audit code for defects, scan for vulnerabilities, or says 'hunt bugs', 'find bugs', or 'code audit'.
drafthq/draft/skills/bughunt/SKILL.md
Performs an exhaustive 14-dimension bug hunt across the codebase using Draft context (architecture, tech-stack, product) for false-positive elimination. Generates a severity-ranked report with code evidence, data flow traces, and suggested fixes. Optionally writes regression tests. Use when the user asks to find bugs, audit code for defects, scan for vulnerabilities, or says 'hunt bugs', 'find bugs', or 'code audit'.
Decision brief
Conduct an exhaustive bug hunt on this Git repository, enhanced by Draft context when available.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/drafthq/draft --skill "skills/bughunt"Inspect the Agent Skill "bughunt" from https://github.com/drafthq/draft/blob/cc8fadf68d4e7fdd20b0acee9ea905a514dee9a6/skills/bughunt/SKILL.md at commit cc8fadf68d4e7fdd20b0acee9ea905a514dee9a6. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
CRITICAL: No bug is valid without verification. Before declaring any finding as a bug, complete ALL applicable verification steps:
1. Code Path Verification - [ ] Read the actual code at the suspected location - [ ] Trace the data flow from input to the bug location - [ ] Check if there are guards, validators, or error handlers upstream - [ ] Verify the code path is actually reachable in production
For suspected bugs that can be tested, write a minimal failing test to confirm:
CRITICAL: All verified bugs appear in the main report body. The Regression Test Suite section organizes test artifacts, but every bug — regardless of whether a test can be written — MUST be documented in the severity sections (Critical/Important/Minor Issues) above. Bugs with N/…
The bug report is the primary deliverable. Every verified bug MUST appear in the final report regardless of whether a regression test can be written. Regression tests are a supplementary output — helpful when possible, but never a filter for bug inclusion.
Permission review
The documentation asks the agent to run terminal commands or scripts.
git branch --show-current # Current branch nameThe documentation asks the agent to run terminal commands or scripts.
git rev-parse --short HEAD # Current commit hashEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 93/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 39 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Conduct an exhaustive bug hunt on this Git repository, enhanced by Draft context when available.
The bug report is the primary deliverable. Every verified bug MUST appear in the final report regardless of whether a regression test can be written. Regression tests are a supplementary output — helpful when possible, but never a filter for bug inclusion.
Some AI tools (e.g., Claude Code) provide a built-in bughunt agent that auto-discovers project structure and runs parallel sweeps. /draft:bughunt is complementary, not competing:
/draft:bughunt | Built-in bughunt agent | |
|---|---|---|
| Approach | Context-driven methodology with 14 analysis dimensions and verification protocol | Auto-discovery with parallel sweep subagents |
| Draft context | Uses architecture, tech-stack, product, guardrails for false-positive elimination | No Draft context awareness |
| Output | Severity-ranked report with evidence | Inline fixes + regression tests |
| Modifies code | No (report + regression tests only) | Yes (finds AND fixes) |
When to use which: Use /draft:bughunt when you need context-aware analysis with structured evidence and false-positive elimination. Use the built-in agent when you want fast parallel sweeps with auto-fix capability. For maximum coverage, run both — /draft:bughunt catches context-specific bugs the built-in misses, and vice versa.
Verify before you report. Evidence over assumptions.
Before starting analysis, capture the current git state:
git branch --show-current # Current branch name
git rev-parse --short HEAD # Current commit hash
Store this for the report header. All bugs found are relative to this specific branch/commit.
Read and follow the base procedure in core/shared/draft-context-loading.md.
Bug-hunt-specific context application:
draft/graph/ exists) — First resolve the bundled helpers:
# Locate Draft's bundled helpers (cwd is the user's project; ${CLAUDE_PLUGIN_ROOT}
# is not exported into skill Bash). See core/shared/tool-resolver.md.
DRAFT_TOOLS="${DRAFT_PLUGIN_ROOT:-$(cat ~/.cache/draft/plugin-root 2>/dev/null)}/scripts/tools"
[ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/cache/*/draft/*/scripts/tools 2>/dev/null | sort -V | tail -1)"
[ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$(ls -d ~/.claude/plugins/marketplaces/*draft*/scripts/tools 2>/dev/null | tail -1)"
[ -d "$DRAFT_TOOLS" ] || DRAFT_TOOLS="$PWD/scripts/tools"
Query "$DRAFT_TOOLS/graph-arch.sh" --repo . for dependency awareness. Flag dependencies on unexpected modules. Flag code in modules involved in dependency cycles as higher risk. Run "$DRAFT_TOOLS/hotspot-rank.sh" --repo . to prioritize analysis of high-complexity, high-fanIn files. See core/shared/graph-query.md.draft/guardrails.md exists, read the ## Learned Anti-Patterns section. During the bug sweep, when a bug matches a learned anti-pattern, prefix the report entry with [KNOWN-ANTI-PATTERN: {pattern name}]. This distinguishes recurring documented patterns from newly discovered bugs, and signals that a systemic fix may be needed rather than a one-off patch.When invoked programmatically by /draft:review with with-bughunt, skip scope confirmation and inherit the scope from the calling command.
Otherwise, ask user to confirm scope:
<track-id>) - Focus on files relevant to a specific trackIf running for a specific track, also load:
draft/tracks/<id>/spec.md - Requirements, acceptance criteria, edge casesdraft/tracks/<id>/plan.md - Implementation tasks, phases, dependenciesUse track context to:
If no Draft context exists, proceed with code-only analysis.
/draft:bughunt can sweep multiple sub-projects in one run — useful at a monorepo root. Trigger it with an explicit directory list (bughunt <dir1> <dir2> ...) or no list (auto-discover).
draft/ directory.draft/ folder, excluding node_modules/, vendor/, .git/, draft/, and dotfiles.<dir>/draft/bughunt-report-latest.md.draft/bughunt-summary.md at the invocation root: a table of dir | Critical | High | Medium | Low | Total | report link, a grand total, and a "directories with Critical issues" callout.draft/) and suggest running /draft:init in them first.For a single target (the common case), skip this section and proceed.
Before analyzing all 14 dimensions, determine which apply to this codebase:
Examples of skipping:
Analyze systematically across all applicable dimensions. Skip N/A dimensions explicitly (see Dimension Applicability Check above).
encode(decode(x)) == x, sorting idempotency, associativity)assertTrue(true), expect(result).toBeDefined() only, empty catch blocks in test code, assert result is not None as sole check)npm audit, pip-audit, cargo audit, go vuln)^, ~, *, >=) without lockfile enforcement, missing lockfile entirelylodahs vs lodash, reqeusts vs requests), recently published packages with few downloads.filter() inside .map(), repeated linear scans, cartesian joins in application code)(a+)+, (a|a)*), unbounded repetition with overlapping alternatives — flag any regex applied to user-controlled input<, >, localeCompare without locale), date formatting (toLocaleDateString without explicit locale), number formatting, sorting (alphabetical sort that assumes ASCII ordering)left/right positioning, directional margin/padding, text alignment assumptions)string.length vs grapheme count), surrogate pair handling in substring operationsCRITICAL: No bug is valid without verification. Before declaring any finding as a bug, complete ALL applicable verification steps:
Code Path Verification
Context Cross-Reference
.ai-context.md (or architecture.md) — Is this behavior intentional by design?tech-stack.md — Does the framework handle this case?tech-stack.md ## Accepted Patterns — Is this pattern explicitly documented as intentional?product.md — Is this actually a requirement violation?Framework/Library Verification
Example Framework Documentation Quote:
"React automatically escapes JSX content to prevent XSS (React Docs: Main Concepts > JSX). However, dangerouslySetInnerHTML bypasses this protection. Framework version: React 18.2.0 (from tech-stack.md)."
Codebase Pattern Check
False Positive Elimination
Pattern Prevalence Check (before reporting)
Example Pattern Prevalence Check:
1. Grep: `rg 'dangerouslySetInnerHTML' src/` → found 12 occurrences
2. Sampled 3: src/Blog.tsx:45, src/About.tsx:12, src/FAQ.tsx:30
3. All 3 sanitize input via `DOMPurify.sanitize()` before rendering
4. THIS instance (src/Comment.tsx:88) passes raw user input without sanitization
5. Decision: REPORT — this instance lacks the sanitization all others have
Only report bugs with HIGH or CONFIRMED confidence:
| Level | Criteria | Action |
|---|---|---|
| CONFIRMED | Verified through code trace, no mitigating factors found | Report as bug |
| HIGH | Strong evidence, checked context, no obvious mitigation | Report as bug |
| MEDIUM | Suspicious but couldn't verify all factors | Ask user to confirm before reporting |
| LOW | Possible issue but likely handled elsewhere | Do NOT report |
Example confirmation prompt for MEDIUM Confidence:
"I found a potential race condition in src/handler.ts:45 where async state updates may overwrite each other. However, I couldn't verify if there's a locking mechanism elsewhere. Should I report this as a bug?"
Each reported bug MUST include:
For suspected bugs that can be tested, write a minimal failing test to confirm:
Example:
// Suspected bug: off-by-one in pagination
test('should handle last page boundary', () => {
const items = Array(100).fill('item');
const result = paginate(items, { page: 10, perPage: 10 });
expect(result.items.length).toBe(10); // Currently returns 9
});
If test fails, upgrade confidence to CONFIRMED and include test in bug report.
For each verified bug, generate a regression test in the project's native test framework that would expose the bug as a failing test. Before writing any new test, discover the project's language and test framework, then check whether existing tests already cover the bug scenario (COVERED / PARTIAL / WRONG_ASSERTION / NO_COVERAGE / N/A).
If no test framework is detected, mark all bugs Regression Test Status: N/A and continue — the bug report is the primary deliverable.
Detailed procedure — see references/regression-tests.md for:
For each bug with CONFIRMED or HIGH confidence, generate a minimal suggested fix alongside the bug report. Fix suggestions are advisory — they are never auto-applied.
SUGGESTED (REVIEW REQUIRED) — never imply auto-application.N/A for bugs where the fix requires architectural changes, significant refactoring, or domain knowledge beyond what the code provides.Reference: Meta SapFix — automated fix suggestion with human-in-the-loop validation.
For each verified bug:
### [SEVERITY] Category: Brief Title
**Location:** `path/to/file.ts:123`
**Confidence:** [CONFIRMED | HIGH | MEDIUM]
**Code Evidence:**
```[language]
// The actual problematic code
Data Flow Trace: [How data reaches this point: caller → caller → this function]
Issue: [Precise technical description of what is wrong]
Impact: [User-visible effect or system failure mode]
Verification Done:
Why Not a False Positive: [Explicit statement: "No sanitization exists because X", "Framework Y doesn't escape Z in this context", etc.]
Fix: [Minimal code change or mitigation]
Suggested Fix (REVIEW REQUIRED):
// BEFORE (current buggy code):
[exact code snippet from the codebase]
// AFTER (suggested fix):
[minimal change that addresses root cause]
This fix is SUGGESTED only — human review required before applying. Reference: Meta SapFix methodology.
Regression Test:
Status: [COVERED | PARTIAL | WRONG_ASSERTION | NO_COVERAGE | N/A]
Existing Test: [path/to/test_file:line — test name | None found]
[Action: existing test reference, proposed modification, or new test case]
// New or modified test case (omit if COVERED or N/A)
**Example — COVERED (no new test needed):**
```markdown
**Regression Test:**
**Status:** COVERED — existing test already catches this bug
**Existing Test:** `tests/validator_test.cpp:89` — `TEST(Validator, RejectsScriptTags)`
No new test needed. Existing test fails when XSS sanitization is removed.
Example — PARTIAL (C++ / GTest):
**Regression Test:**
**Status:** PARTIAL — tests exist for processInput() but miss unsanitized HTML path
**Existing Test File:** `tests/input_test.cpp`
**Modification:** Add to existing file:
```cpp
TEST(InputSanitization, RejectsMaliciousScript) {
std::string malicious = "<script>alert('xss')</script>";
std::string result = processInput(malicious);
EXPECT_EQ(result.find("<script>"), std::string::npos)
<< "Input should be sanitized to remove script tags";
}
**Example — NO_COVERAGE (Python / pytest):**
```markdown
**Regression Test:**
**Status:** NO_COVERAGE — no tests found for process_input()
**Target File:** `tests/test_input_processor.py` (new file)
```python
import pytest
from input.processor import process_input
def test_rejects_malicious_script():
"""Input should be sanitized to remove script tags."""
malicious = "<script>alert('xss')</script>"
result = process_input(malicious)
assert "<script>" not in result, "XSS script tag should be stripped"
# Expected: FAILS against current code (passes XSS through), PASSES after fix
**Example — NO_COVERAGE (Go / testing):**
```markdown
**Regression Test:**
**Status:** NO_COVERAGE — no tests found for ProcessInput()
**Target File:** `input/processor_test.go` (new file)
```go
package input
import (
"strings"
"testing"
)
func TestProcessInputRejectsMaliciousScript(t *testing.T) {
malicious := "<script>alert('xss')</script>"
result := ProcessInput(malicious)
if strings.Contains(result, "<script>") {
t.Error("XSS script tag should be stripped from input")
}
}
// Expected: FAILS against current code (passes XSS through), PASSES after fix
**Example — N/A (not testable, but still report the bug):**
```markdown
**Regression Test:**
**Status:** N/A — environment config, no executable code path
**Reason:** Bug is in `config/production.yaml` which sets incorrect timeout value. Config files are not unit-testable; fix requires changing the YAML value directly.
Severity levels:
Generate report at:
draft/bughunt-report-<timestamp>.md (where <timestamp> is generated via date +%Y-%m-%dT%H%M, e.g., 2026-03-15T1430)draft/tracks/<track-id>/bughunt-report-<timestamp>.md (if analyzing specific track)After writing the timestamped report, create a symlink pointing to it:
# Project-level
ln -sf bughunt-report-<timestamp>.md draft/bughunt-report-latest.md
# Track-level
ln -sf bughunt-report-<timestamp>.md draft/tracks/<track-id>/bughunt-report-latest.md
Previous timestamped reports are preserved. The -latest.md symlink always points to the most recent report.
MANDATORY: Include YAML frontmatter with git metadata. Follow the procedure in core/shared/git-report-metadata.md to gather git info and generate the frontmatter. Use generated_by: "draft:bughunt".
Report structure:
[YAML frontmatter — see core/shared/git-report-metadata.md]
# Bug Hunt Report
[Report header table — see core/shared/git-report-metadata.md]
**Scope:** [Entire repo | Specific paths | Track: <track-id>]
**Draft Context:** [Loaded | Not available]
## Summary
| Severity | Count | Confirmed | High Confidence |
|----------|-------|-----------|-----------------|
| Critical | N | X | Y |
| Important | N | X | Y |
| Minor | N | X | Y |
## Critical Issues
[Issues...]
## Important Issues
[Issues...]
## Minor Issues
[Issues...]
## Dimensions With No Findings
| Dimension | Status |
|-----------|--------|
| Correctness | No bugs found |
| Reliability | N/A — no runtime application |
| Performance | N/A — static site, no dynamic content |
| Concurrency | N/A — no async operations |
## Regression Test Suite
**Language:** [detected language]
**Test Framework:** [detected framework]
**Validation Command:** [command used]
### Test Discovery Summary
| # | Bug Title | Severity | Status | Existing Test | Action |
|---|-----------|----------|--------|---------------|--------|
| 1 | [Brief title] | [SEV] | COVERED | `path:line` | None needed |
| 2 | [Brief title] | [SEV] | PARTIAL | `path:line` | Added case to existing file |
| 3 | [Brief title] | [SEV] | WRONG_ASSERTION | `path:line` | Fixed assertion |
| 4 | [Brief title] | [SEV] | NO_COVERAGE | — | Created new test |
| 5 | [Brief title] | [SEV] | N/A | — | Not testable |
### Validation Status
| # | Bug Title | Test File / Target | Validation Status |
|---|-----------|-------------------|-------------------|
| 2 | [Brief title] | `tests/test_foo.py` | BUILD_OK (modified) |
| 3 | [Brief title] | `tests/test_bar.py:67` | BUILD_OK (modified) |
| 4 | [Brief title] | `tests/test_baz.py` | BUILD_OK (new) |
| 5 | [Brief title] | — | SKIPPED (N/A) |
Validation Summary: 3 BUILD_OK, 0 BUILD_FAILED, 1 SKIPPED Validation Command: python -m py_compile
### New Tests Written (NO_COVERAGE)
New test files created for bugs with no existing test coverage.
| Bug # | File Created | Build Target / Runner |
|-------|-------------|----------------------|
| 4 | `tests/test_baz.py` | `pytest tests/test_baz.py` |
```[language]
// Contents of new test file
Changes applied to existing test files.
| File | Bug # | Change Applied |
|---|---|---|
tests/test_foo.py | 2 | Added test_missing_case() |
tests/test_bar.py:67 | 3 | Changed assert result == 0 → assert result == 1 |
Bugs already caught by existing tests — no action needed.
| Bug # | Bug Title | Existing Test |
|---|---|---|
| 1 | [Brief title] | tests/test_foo.py:45 — test_sanitize_input() |
Bugs that cannot have automated regression tests (config issues, documentation, LLM workflows, etc.).
| Bug # | Bug Title | Reason |
|---|---|---|
| 6 | [Brief title] | Config file — no executable code |
## Final Instructions
**CRITICAL: All verified bugs appear in the main report body.** The Regression Test Suite section organizes test artifacts, but every bug — regardless of whether a test can be written — MUST be documented in the severity sections (Critical/Important/Minor Issues) above. Bugs with `N/A` regression test status are still valid bugs that need reporting.
**CRITICAL: Regression tests are supplementary, not a filter.** If no test framework is detected, or if a bug cannot have a test written (config, docs, LLM workflows), mark it as `N/A` and **still include the bug in the report**. Never skip a verified bug because you cannot write a test for it.
- **No unverified bugs** — Every finding must pass the verification protocol
- **Evidence required** — Include code snippets and trace for every bug
- **Explicit false positive elimination** — State why each bug isn't handled elsewhere
- Analyze all applicable dimensions — skip N/A dimensions explicitly with reason (see Dimension Applicability Check)
- Assume the reader is a senior engineer who will verify your findings
- If Draft context is available, explicitly note which architectural violations or product requirement bugs were found
- Be precise about file locations and line numbers
- Include git branch and commit in report header
- **Write regression tests when possible** — If a test framework is detected, write test files using the project's native framework (Steps 4-6). If no framework exists, skip Steps 2-6 and mark all bugs as `N/A` for regression tests
- **Never modify production code** — Only create/modify test files and their build configs
- **Validate before reporting** — If tests were written, validate syntax/compilation before finalizing; include validation status in the report
- **Respect project conventions** — Match existing test directory structure, naming patterns, import conventions, and framework idioms
- **Use native frameworks** — pytest for Python, `go test` for Go, GTest for C++, Jest/Vitest for JS/TS, `cargo test` for Rust, JUnit for Java — never force a foreign test framework
- **Learn from findings** — After report generation, execute the pattern learning phase from `core/shared/pattern-learning.md` to update `draft/guardrails.md` with newly discovered conventions and anti-patterns
---
## Cross-Skill Dispatch
### Suggestions at Completion
After bughunt report generation:
**If critical bugs found:**
"Critical bugs found. Consider: → /draft:debug — Run structured debug session on critical finding #{n} → git bisect — Find the exact commit that introduced the bug"
### Test Writing Guardrail
When offering to write regression tests for found bugs:
ASK: "Want me to write regression tests for the {n} bugs found? [Y/n]"
Never auto-write tests — always ask first.
### Jira Sync
If Jira ticket linked, sync via `core/shared/jira-sync.md`:
- Attach `bughunt-report-latest.md` to ticket
- Post comment: "[draft] bughunt-complete: Found {n} issues — {critical} critical, {major} major."
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
JasonColapietro/suede-creator-skills
Suede-owned experimentation discipline for hypotheses, sample sizing, test duration, significance, and repeatable experiment programs. Use when comparing variants, deciding whether a result is reliable, or building an experiment backlog and cadence. NOT FOR: analytics instrumentation (use suede-analytics), post-click conversion diagnosis (use suede-site-alchemy), or writing the variant copy itself (use suede-copy).
narrative-io/narrative-skills-marketplace
Translate a fuzzy analytical question into a rigorous investigation plan. Interrogates the ask, grounds the plan in the available data dictionary, applies analytical best practices, and produces a structured brief of query specifications for a downstream query-writing skill. Plans, does not write SQL. Use when: "why did X drop", "is there a relationship between A and B", "who are our highest-value customers", "what's driving the change in Y", "investigate this trend", "design an analysis for", "