with one click
bug
Triage a bug report through structured phases and create micro-sprint
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Triage a bug report through structured phases and create micro-sprint
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Bridgebuilder — Autonomous PR Review
Launch PRD discovery with codebase grounding and context ingestion
Execute sprint tasks with production-quality code and tests
Validate sprint implementation against acceptance criteria
Security and quality audit of application codebase
Autonomous agent execution mode
| name | bug |
| description | Triage a bug report through structured phases and create micro-sprint |
| role | implementation |
| context | fork |
| agent | general-purpose |
| parallel_threshold | 3000 |
| timeout_minutes | 60 |
| zones | {"system":{"path":".claude","permission":"none"},"state":{"paths":["grimoires/loa",".beads",".run"],"permission":"read-write"},"app":{"paths":["src","lib","app"],"permission":"read"}} |
| capabilities | {"schema_version":1,"read_files":true,"search_code":true,"write_files":true,"execute_commands":true,"web_access":false,"user_interaction":true,"agent_spawn":true,"task_management":false} |
| cost-profile | heavy |
| inputs | [{"path":"grimoires/loa/known-failures.md","why":"Context-Intake Discipline — read first (is this a known failure?)"},{"path":".claude/rules/zone-state.md","why":"State-Zone rules for the micro-sprint artifacts"}] |
<input_guardrails>
Skip this section entirely when .loa.config.yaml has guardrails.input.enabled: false or env
LOA_GUARDRAILS_ENABLED=false.
Otherwise: write the user's invocation prompt/args to a temp file (Write tool), then run
.claude/scripts/guardrails-orchestrator.sh --skill bug-triaging --mode ${LOA_RUN_MODE:-interactive} --file <temp-file>
| Outcome | Action |
|---|---|
JSON action: "BLOCK" | HALT; report the script's reason to the user |
JSON action: "PROCEED" or "WARN" | Continue (logging is handled by the script) |
| Script missing, non-zero exit, or unparseable output | Continue — fail-open, preserving pre-cycle-119 semantics |
Never pass prompt text as a bash argv (quote-blindness FP class) — always via --file.
</input_guardrails>
<prompt_enhancement_prelude>
If .loa.config.yaml sets prompt_enhancement.invisible_mode.enabled: true and this command's
frontmatter does not set enhance: false, silently apply the PTCF scoring + template flow from
.claude/skills/enhancing-prompts/SKILL.md to the user's request before main logic (log per that
skill; never show enhancement output). On any error, or when disabled: proceed with the original
prompt unchanged.
</prompt_enhancement_prelude>
Triage a reported bug through structured phases: validate eligibility, gather details,
analyze codebase, and produce a handoff contract for /implement. Bugs always get their
own micro-sprint. Test-first is non-negotiable.
/bug — redirect to /planCheck required and optional tools before proceeding.
| Tool | Check | On Missing |
|---|---|---|
jq | command -v jq | HALT: "Install jq: brew install jq / apt install jq" |
git | command -v git | HALT: "Git is required for branch creation" |
| Tool | Check | On Missing |
|---|---|---|
gh | command -v gh | WARN if --from-issue used: "Run gh auth login first". Fallback: ask user to paste issue content. |
br | command -v br | WARN: "Beads not available. Task tracking will be skipped." Continue without beads. |
If --from-issue is used:
gh auth status succeedsgh auth login first"1. Check required tools (jq, git)
- If ANY missing → HALT with install guidance
2. Check optional tools (gh, br)
- If gh missing AND --from-issue used → HALT with auth guidance
- If gh missing AND no --from-issue → continue (not needed)
- If br missing → WARN and continue without beads
3. If --from-issue: verify gh auth status
- If not authenticated → HALT
4. Log tool availability to triage output
| Failure | Action | Recovery |
|---|---|---|
| jq missing | HALT | "Install jq: brew install jq / apt install jq" |
| git missing | HALT | "Git is required" |
| gh not authenticated | HALT | "Run gh auth login first" |
| gh missing + --from-issue | HALT | "Install GitHub CLI: brew install gh" |
| gh missing (no --from-issue) | Continue | Not needed for manual input |
| br not found | WARN | "Beads not available. Task tracking will be skipped." |
Validate that the reported issue is actually a bug (not a feature request) and has sufficient evidence to proceed.
| Source | When | How |
|---|---|---|
| Free-form text | /bug "description" | Parse directly |
| GitHub issue | /bug --from-issue N | gh issue view N --json title,body,comments |
| Interactive | /bug (no args) | Prompt user for description |
Before processing any imported content (especially from gh issue view):
sk-[a-zA-Z0-9]{32,}, AKIA[0-9A-Z]{16}eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+Bearer [a-zA-Z0-9_-]+password[=:]\s*\S+\+?[0-9]{10,15}[REDACTED_API_KEY], [REDACTED_JWT], Bearer [REDACTED]password=[REDACTED], [REDACTED_EMAIL], [REDACTED_PHONE]test@example.com, 127.0.0.1, hex strings < 16 charsParse input for verifiable artifacts:
| Signal | Points | Verification |
|---|---|---|
| Failing test name (executable) | +2 | Run the test |
| Reproducible steps (can be followed) | +2 | Follow the steps |
| Stack trace with source locations | +1 | file:line exists |
| Error log from production incident | +1 | Log is attached |
| References regression from known baseline | +1 | Commit/version cited |
Check for explicit disqualifiers. ANY match → immediate REJECT:
| Disqualifier | Signal |
|---|---|
| New endpoint or API route | "add endpoint", "new route", "create API" |
| New UI flow or page | "add page", "new screen", "design", "dark mode" |
| Schema change or new tables | "add column", "new table", "migration" |
| Cross-service architectural changes | "microservice", "new service" |
| New configuration options | "add setting", "new config" |
IF any disqualifier matched:
→ REJECT: "This looks like a feature request. Use /plan instead."
IF score < 2:
→ REJECT: "Insufficient evidence of a bug. Provide a stack trace, failing test, or repro steps."
IF score == 2:
→ CONFIRM: "This is borderline. Please confirm: is this a defect in existing behavior?"
→ If user confirms: proceed
→ If user declines: REJECT
IF score > 2:
→ ACCEPT: proceed to Phase 2
| Input | Score | Decision | Reason |
|---|---|---|---|
| "Login fails with + in email" + stack trace | 3 | ACCEPT | Repro steps (+2) + stack trace (+1) |
| "Add dark mode support" | REJECT | REJECT | Disqualifier: new UI flow |
| "API returns 500 on empty cart" (no trace) | 2 | CONFIRM | Repro steps only (+2) |
| "Test test_checkout fails after deploy" | 3 | ACCEPT | Failing test (+2) + regression (+1) |
| "We need a logout button" | REJECT | REJECT | Disqualifier: new feature |
Some bugs legitimately require changes matching disqualifiers (e.g., backward-compatible schema fix for data corruption). The CONFIRM path handles this:
| Failure | Action | Recovery |
|---|---|---|
| --from-issue fetch fails | Fallback | Ask user to paste issue content |
| Score ambiguous (==2) | CONFIRM | Ask user to verify it's a bug |
| PII detected in import | Quarantine | Redact and show user what was removed |
Log classification decision to triage.md metadata:
eligibility_score: numeric scoreeligibility_reasoning: human-readable explanation of signals found/missingFill gaps in the bug report through targeted follow-up questions.
| Field | Description | Can Infer? |
|---|---|---|
reproduction_steps | Steps to reproduce the bug | Only from stack trace |
expected_behavior | What should happen | No |
actual_behavior | What actually happens | Partially from error |
severity | critical / high / medium / low | Partially |
| Field | Description | Inference Source |
|---|---|---|
affected_area | Module or subsystem | Stack trace, file paths |
environment | local / staging / production | Context clues |
1. Parse free-form input for known fields:
- Look for "steps to reproduce", "expected", "actual", "severity"
- Extract from structured GitHub issue templates
- Parse stack traces for implicit reproduction info
2. Identify gaps:
gaps = required_fields - detected_fields
3. For each gap, generate one targeted question:
- reproduction_steps: "Can you describe the exact steps to trigger this bug?"
- expected_behavior: "What should happen instead?"
- actual_behavior: "What error or incorrect behavior do you see?"
- severity: "How severe is this? (critical=production down, high=major feature broken, medium=workaround exists, low=cosmetic)"
4. Ask max 3-5 questions total (batch remaining gaps)
5. If user cannot provide reproduction steps:
- WARN: "Without repro steps, fix may take longer. Proceed?"
- If yes: mark reproduction_strength = "weak"
- If no: HALT
1. Parse input for all known fields
2. Count gaps in required fields
3. If gaps == 0: skip interview, proceed to Phase 3
4. If gaps > 0: ask targeted questions (max 5)
5. After answers: validate all required fields present
6. Set reproduction_strength:
- "strong": explicit repro steps OR failing test
- "weak": only error message, no repro steps
- "manual_only": requires manual verification
| Failure | Action | Recovery |
|---|---|---|
| User can't provide repro steps | WARN | Mark reproduction_strength="weak", ask to confirm |
| Contradictory info | ASK | Clarifying question to resolve |
| User abandons interview | HALT | Save partial triage state |
Analyze the codebase to identify suspected files, existing tests, and test infrastructure.
1. Parse stack traces → extract file:line references
- Use Grep to verify file:line references exist
- Extract function/method names from stack frames
2. Keyword search: search codebase for function/module names from error
- Use Grep with function names, error messages, class names
- Limit to relevant source directories (src/, lib/, app/)
3. Dependency mapping: trace imports/requires from affected files
- Read suspected files
- Follow import chains 1-2 levels deep
- Note shared dependencies
4. Test discovery: find test files matching affected modules
- Glob for test files: **/*.test.*, **/*.spec.*, **/test_*.*, **/*_test.*
- Match test files to suspected source files by name/path
5. Test infrastructure detection:
- Search for test runners:
| Runner | Detection |
|--------|-----------|
| jest | package.json "jest" or jest.config.* |
| vitest | vitest.config.* or package.json "vitest" |
| pytest | pytest.ini, pyproject.toml [tool.pytest], conftest.py |
| cargo test | Cargo.toml |
| go test | *_test.go files |
| mocha | .mocharc.*, package.json "mocha" |
- If NO test runner found: HALT
"No test runner detected. Set up test infrastructure before using /bug."
6. Determine test_type based on bug classification:
| Classification | Test Type |
|---------------|-----------|
| runtime_error, logic_bug | unit |
| integration_issue | integration |
| edge_case (user-facing) | e2e |
| schema/contract violation | contract |
7. Check high-risk patterns in suspected files:
| Pattern | Risk |
|---------|------|
| auth, authentication, login, password, token, jwt, oauth | high |
| payment, billing, charge, stripe, checkout | high |
| migration, schema, database, db | high |
| encrypt, decrypt, secret, credential, key | high |
| All other files | low/medium |
Produce a list of suspected files with:
In addition to the prose fix_strategy, generate structured fix_hints for each
suspected file change. These enable smaller models (e.g., 3B parameter fast-code)
to act on the fix without parsing nuanced prose:
| Field | Description | Example |
|---|---|---|
file | Source file path | src/auth/login.ts |
action | What to do: fix, add, remove, refactor, encode, validate | encode |
target | What specifically to change | email parameter |
constraint | Scope limitation or condition | login path only |
Generate one hint per suspected file. Prose fix_strategy remains the primary
reference for capable models; hints are the structured fallback.
| Failure | Action | Recovery |
|---|---|---|
| No test runner found | HALT | "Set up test infrastructure before using /bug" |
| No suspected files found | WARN | Ask user for hints, expand search radius |
| All files low confidence | WARN | "Analysis inconclusive. Recommend manual investigation." |
Create the micro-sprint, register in ledger, and produce the handoff contract.
Generate bug_id:
timestamp = YYYYMMDD (current date)
random = 6 random hex characters (from openssl rand -hex 3)
If --from-issue N:
bug_id = "{timestamp}-i{N}-{random}"
Else:
bug_id = "{timestamp}-{random}"
Examples:
"20260211-a3f2b1"
"20260211-i42-a3f2b1"
Properties:
1. Create directory: .run/bugs/{bug_id}/
2. Write state file using atomic write:
state = {
"schema_version": 1,
"bug_id": "{bug_id}",
"bug_title": "{sanitized_title}",
"sprint_id": "sprint-bug-{NNN}",
"state": "TRIAGE",
"mode": "interactive" | "autonomous",
"created_at": "{ISO 8601}",
"updated_at": "{ISO 8601}",
"circuit_breaker": {
"cycle_count": 0,
"same_issue_count": 0,
"no_progress_count": 0,
"last_finding_hash": null
},
"confidence": {
"reproduction_strength": "{strong|weak|manual_only}",
"test_type": "{unit|integration|e2e|contract}",
"risk_level": "{low|medium|high}",
"files_changed": 0,
"lines_changed": 0
}
}
# Atomic write pattern:
tmp=$(mktemp ".run/bugs/${bug_id}/state.json.XXXXXX")
echo "$json" > "$tmp"
mv "$tmp" ".run/bugs/${bug_id}/state.json"
TRIAGE → IMPLEMENTING (triage complete, implement begins)
IMPLEMENTING → REVIEWING (implementation complete)
REVIEWING → IMPLEMENTING (review found issues — loop back)
REVIEWING → AUDITING (review passed)
AUDITING → IMPLEMENTING (audit found issues — loop back)
AUDITING → COMPLETED (audit passed — COMPLETED marker created)
ANY → HALTED (circuit breaker triggered or manual halt)
Invalid transitions (e.g., TRIAGE → AUDITING) must be rejected with an error.
1. Pick the next safe sprint id via the helper script:
sprint_id="$(.claude/scripts/next-bug-sprint-id.sh)"
The script is the source-of-truth for next-id picking. It returns
`sprint-bug-{N}` where N is one greater than the maximum of:
a) local ledger.json's global_sprint_counter
b) max sprint-bug-N referenced on disk in any
grimoires/loa/a2a/bug-*/sprint.md
c) origin/main's ledger.json's global_sprint_counter (best-effort)
This avoids the collision wart where multiple `/bug` invocations
from the same starting commit would all pick the same N+1 because
they each only consulted local ledger state. See
tests/unit/next-bug-sprint-id.bats for the contract.
2. Create micro-sprint file from template:
Path: grimoires/loa/a2a/bug-{bug_id}/sprint.md
Template: .claude/skills/bug-triaging/resources/templates/micro-sprint.md
Fill placeholders: {bug_title}, {bug_id}, {sprint_id}, {test_type},
{suggested_test_file}, {suspected_files}
4. Create triage.md from template:
Path: grimoires/loa/a2a/bug-{bug_id}/triage.md
Template: .claude/skills/bug-triaging/resources/templates/triage.md
Fill all placeholders from Phase 1-3 results
5. Apply PII redaction to both output files before final write
6. MUST run `.claude/scripts/validate-artifact.sh --type bug-triage --file grimoires/loa/a2a/bug-{bug_id}/triage.md`;
repair per its output on exit 1 before proceeding to ledger registration;
exit 2 (usage/file-not-found) is a validator FAILURE — fix the path and
re-run, do not proceed
1. Read grimoires/loa/ledger.json
2. Add bugfix cycle entry:
{
"id": "cycle-bug-{bug_id}",
"label": "Bug Fix — {sanitized_title}",
"type": "bugfix",
"status": "active",
"source_issue": "{issue_url_or_null}",
"created_at": "{ISO 8601}",
"sprints": ["{sprint_id}"],
"triage": "grimoires/loa/a2a/bug-{bug_id}/triage.md",
"sprint_plan": "grimoires/loa/a2a/bug-{bug_id}/sprint.md"
}
3. Set global_sprint_counter to the integer N from sprint_id
(NOT just `+= 1` from local — the helper may have picked a higher
N from disk-scan or origin/main, so the ledger must catch up to it).
Pattern: `counter = sprint_id.split("-")[-1] | tonumber`
4. Write using atomic temp + rename pattern
If br is available:
1. Create beads task:
br create "Fix: {bug_title}" --label bug --label "severity:{severity}"
2. If create fails: WARN and continue without tracking
If br is NOT available:
1. Log: "Beads not available. Task tracking skipped."
2. Continue without beads
Before writing any output files, scan for PII:
After Phase 4 completes, the triage is done. Output:
Bug triage complete.
Bug ID: {bug_id}
Sprint: {sprint_id}
Test Type: {test_type}
Risk Level: {risk_level}
Repro: {reproduction_strength}
Triage: grimoires/loa/a2a/bug-{bug_id}/triage.md
Sprint: grimoires/loa/a2a/bug-{bug_id}/sprint.md
Next step: /implement {sprint_id}
In interactive mode, the user runs /implement manually.
In autonomous mode (/run --bug), implementation begins automatically.
| Failure | Action | Recovery |
|---|---|---|
| Ledger write fails | WARN | Proceed without ledger entry, note in NOTES.md |
| Beads create fails | WARN | Proceed without beads, note in NOTES.md |
| State directory creation fails | HALT | Filesystem issue, cannot proceed |
| PII found in output | Redact | Replace with tokens, log categories |
After triage completion, check for learning signals:
If qualified (3+ quality gates), add to grimoires/loa/NOTES.md ## Learnings.