Task(debugger):
"Bug Description: {user input}
Error Output: {error logs, if available}
Context: {related files/recent changes, if available}
Investigate this bug following your Investigation Protocol.
Classify Bug Type, trace backward to root cause, assess Severity."
Task(verification-planner):
"User's Goal: Fix the bug described below
Current Understanding: {user input}
Work Breakdown:
- Reproduce bug with test
- Apply minimal fix at root cause
- Verify fix resolves the issue
Focus on Auto items only (what commands prove the fix works).
Keep it minimal — this is a bug fix, not a feature.
Note: /bugfix uses Tier 1-3 (Auto items) only. Do not inline VERIFICATION.md.
Tier 4 (sandbox items) are not needed. Mark sandbox section as 'bugfix mode — Tier 1-3 only'."
After receiving debugger results, update debug-state.md:
Task(gap-analyzer):
"User's Goal: Fix the bug below
Current Understanding: {debugger's full Bug Analysis Report}
Intent Type: Bug Fix
Focus on:
- Whether root cause vs symptom distinction is correct
- Whether proposed fix could break other areas
- Whether similar bugs exist with the same pattern"
Step 1.3b: Blast-radius Quick Scan
After debugger identifies root_cause.location (e.g. src/auth/token.ts:42), extract the function/module name and run grep-based structural scan. Always use wc -l so the LLM compares integers, not raw grep output.
# Extract from debugger's Root Cause section:# fn = function or symbol name at the root cause (e.g. "parseToken")# mod = module path without extension (e.g. "src/auth/token")# If the function name cannot be reliably extracted, set fn="" and skip caller_count.
total_files=$(git ls-files | wc -l | tr -d ' ')
callers=$(git grep -l -F "$fn" 2>/dev/null | wc -l | tr -d ' ')
importers=$(git grep -l -F "$mod" 2>/dev/null | wc -l | tr -d ' ')
test_refs=$(git grep -l -F "$fn" -- '**/*test*''**/*spec*' 2>/dev/null | wc -l | tr -d ' ')
hot_path=$(git grep -l -F "$fn" -- 'migrations/**''auth/**''payment/**''billing/**''schema/**' 2>/dev/null | wc -l | tr -d ' ')
Use -F (fixed string) to avoid regex injection from extracted symbols. Empty or malformed symbols → skip that signal, do NOT fail the phase.
Present debugger results + blast-radius scan + triage hint for user confirmation.
The triage hint is advisory — the user always makes the final routing decision.
AskUserQuestion:
header: "Root Cause & Triage"
question: "Review diagnosis and choose how to proceed."
Display:
- Bug Type: [classification]
- Root Cause: [file:line + 1-line description]
- Proposed Fix: [change description — 1 line]
- Verification: [verification commands from verification-planner]
- Assumptions: [debugger's Assumptions section]
- Key warnings from Gap Analysis
- Blast Radius: callers={N}, importers={M}, tests={T}, hot_path={H}
- Triage: {hint from Step 1.3c} — {reason}
(e.g. "/specify recommended — touches auth/ (hot path)")
options:
- "Continue with bugfix" → Phase 2
(if triage hint != bugfix, show as "Continue with bugfix (override triage)")
- "Switch to /specify" → Hand off requirements.md + debug-state.md to /specify
- "Switch to /discuss" → Exit bugfix, suggest running /discuss with the bug context
- "Root cause is different" → Re-run Step 1.2 with user's additional info
- "Stop" → Exit
Handoff on /specify selection:
# requirements.md hasn't been written yet (Phase 2 is skipped on handoff),
# but debug-state.md contains all Phase 1 findings. Save a skeleton so /specify
# has a starting point, then exit bugfix.
hoyeon-cli req init ${SPEC_DIR} --type bugfix --goal "Fix: {bug description}"
# Append debugger report + blast scan to ${SPEC_DIR}/requirements.md as context
# (sections: ## Debug Context, ## Blast Radius)
Update DEBUG_STATE: status: escalated, reason: "user_triage_specify"
print("Handed off to /specify. Run: /specify {SPEC_DIR}")
Phase 2: REQUIREMENTS GENERATION
Convert diagnosis results into requirements.md format. requirements.md is the standard format consumed by /execute, and serves as escalation context for /specify on failure.
This creates ${SPEC_DIR}/requirements.md with a stub template.
Step 2.2: Write requirements content
Overwrite ${SPEC_DIR}/requirements.md with the full requirements derived from diagnosis results. Use the Write tool directly.
What to include:
---
type: bugfix
goal: "Fix: {bug description}"
non_goals:
- "No refactoring beyond the fix"
- "No unrelated feature changes"
---
# Requirements
## R-B1: {Bug fix requirement title — describes the broken behavior}
- behavior: {one-sentence description of what should work correctly after fix}
#### R-B1.1: {sub-requirement — the core bug scenario}
- given: {the precondition/state that triggers the bug}
- when: {the action that exercises the broken path}
- then: {the expected (post-fix) outcome — what "fixed" looks like}
#### R-B1.2: {sub-requirement — edge case or similar issue, if any}
- given: {precondition for the edge case}
- when: {action that triggers it}
- then: {expected outcome}
## R-T1: Minimal diff constraint
- behavior: Fix targets root cause only with minimal code changes
#### R-T1.1: Root cause targeting
- given: {root cause identified at file:line}
- when: the fix is applied
- then: only the root cause location is modified, no unrelated changes
## Constraints
- Minimal diff (<5% of codebase)
- Fix root cause, not symptom
- No refactoring beyond what the fix requires
Mapping rules:
Convert debugger's reproduction steps into GWT (given/when/then) for each sub-requirement
given: the precondition/state that triggers the bug
when: the action that exercises the broken path
then: the expected (post-fix) outcome
If debugger identified edge cases / similar issues, add sub-requirements for each (one sub per scenario)
Include a constraints section with fix-scope guardrails
Step 2.3: Register
hoyeon-cli session set --sid $SESSION_ID --spec "$SPEC_DIR"
Update debug-state.md with spec_dir: ${SPEC_DIR}.
Phase 3: EXECUTE
Hand off requirements.md to /execute. Execute2 reads requirements.md from the spec dir and derives plan.json internally.
Skill("execute", args="${SPEC_DIR}")
What execute handles:
Prompts the user for dispatch / work / verify via AskUserQuestion
Worker dispatch according to the chosen dispatch mode
Round-level commit
Verify recipe according to the chosen verify depth
Final report
Result judgment:
IF execute completed successfully (all tasks done, report output):
→ Phase 5
IF execute HALTED:
→ Phase 4
Phase 4: RESULT HANDLING
When execute HALTs.
Step 4.1: Read Failure Context
# Extract failure reason from execute's HALT output
# or read from context dir's audit.md, issues.json
CONTEXT_DIR = "${SPEC_DIR}/context"
failure_reason = {execute HALT output or last triage result from audit.md}
Step 4.2: Retry
# Read current attempt from debug-state.md
attempt = debug_state.attempt + 1
MAX_ATTEMPTS = 3
IF attempt >= MAX_ATTEMPTS:
→ Step 4.5 (Circuit Breaker)
Stagnation Detection (attempt >= 2):
# Compare with previous attempt failure info
previous = debug_state.Attempts[-1]
current_reason = failure_reason
SPINNING: same file/component fails consecutively
OSCILLATION: A fails → B fails → A fails (circular)
NO_PROGRESS: different failures each time, previous fixes cause regressions
Pattern-specific retry_hint:
SPINNING → "Different root cause likely. Consider: previous root cause
was wrong — trace further back from the symptom."
OSCILLATION → "Circular dependency. Fix both sides simultaneously."
NO_PROGRESS → "Fundamental misunderstanding. Re-read error output.
Consider: multiple independent bugs? Missing dependency?"
(no pattern) → "Different approach needed. Do NOT repeat previous attempt."
Step 4.4: Update Requirements & Re-execute
# 1. Record attempt in debug-state.md
Append to DEBUG_STATE ## Attempts section:
### Attempt {attempt}
result: FAIL
reason: {failure_reason}
pattern: {detected pattern or "none"}
hint: {retry_hint}
# 2. Update attempt counter
Update DEBUG_STATE: attempt: {attempt}
# 3. Add failure context to requirements.md
# Read current requirements.md, append failure context to the Constraints
# section or add a "## Known Issues" section with the failure info and
# retry hint so the next worker has context.
# Use Edit tool to append to requirements.md.
# 4. Re-invoke execute
# /execute reads plan.json next to requirements.md. Do NOT touch plan.json
# directly from bugfix — /execute handles task status and re-derivation.
# If you need to reset failed tasks to pending so /execute will re-run them,
# do it via the plan CLI:
# hoyeon-cli plan list ${SPEC_DIR}
# hoyeon-cli plan task ${SPEC_DIR} --status <task-id>=pending
# In most cases /execute will resume on its own from the existing plan.json.
# 5. Re-invoke execute
→ Phase 3
Execute2 handles resume naturally:
Reads existing plan.json and skips done tasks
Context files (learnings.json, issues.json — in the context dir) retain previous failure info for the new worker
Known Issues section in requirements.md carries failure context and retry_hint for the worker
Step 4.5: Circuit Breaker
Max attempts exceeded. Present escalation options to user.
AskUserQuestion:
header: "Circuit Breaker"
question: "Fix attempts have failed. This may be an architecture-level issue."
options:
- "Switch to /specify (full planning)"
→ "requirements.md and debug report are available:
Spec Dir: {SPEC_DIR}
Report: .hoyeon/debug/{slug}.md
/specify can reference this context for deeper analysis."
- "Try once more"
→ attempt += 1, go to Phase 3 (no circuit breaker reset)
- "Stop"
Phase 5: CLEANUP & REPORT
After execute completes successfully.
Step 5.1: Save Debug Report
Bash: mkdir -p .hoyeon/debug
Write to .hoyeon/debug/{slug}.md:
# Bugfix Report: {description}
Date: {timestamp}
Status: RESOLVED
Attempts: {attempt count + 1}
Spec Dir: {SPEC_DIR}
## Root Cause
{debugger's Root Cause analysis}
## Fix
{proposed fix from debugger + result summary from /execute's final report}
## Verification
{verification results from execute's final report}
Update DEBUG_STATE:
status: resolved
After successful fix, offer QA verification via browser/app:
AskUserQuestion:
header: "QA"
question: "Fix complete. Run QA to verify in browser/app?"
options:
- "Yes — run /qa"
→ Skill("qa", args="Verify bugfix: {description}. Root cause was at {file:line}. Check that the fix works and no regressions.")
- "No — done"
→ End
Since requirements.md is the standard format, /specify can read and enrich the existing requirements on escalation. All diagnosis context (constraints, known issues, GWT scenarios) is preserved.
Agent Summary
Phase
Agent
Status
Condition
Role
1
debugger
existing
always
Root cause analysis, Bug Type classification
1
verification-planner
existing
always
Generate Auto items list (verification commands)
1
gap-analyzer
existing
always
Check for missed factors, risk assessment
1.5
Bash (git grep + wc -l)
new
always
Blast-radius scan + triage hint (no agent, direct grep)