Automate complete bug lifecycle - triage, reproduce, investigate, plan, fix, verify, document RCA
Automates: triage → reproduce → investigate → plan → fix → verify → document.
Invocation:
/bug-fix 278 - Full execution/bug-fix 278 --dry-run - Simulation mode (no writes, no PR, no comments)When --dry-run is passed:
| Action | Normal | Dry Run |
|---|---|---|
| Fetch issue | Execute | Execute (read-only) |
| Navigate browser | Execute | Execute (read-only) |
| Take screenshots | Execute | Execute (save locally only) |
| Capture console/network | Execute | Execute |
| Write state file | Execute | SKIP - print what would be written |
| Post issue comment | Execute | SKIP - print comment content |
| Add labels | Execute | SKIP - print labels |
| Create plan file | Execute | SKIP - print content |
| Create worktree | Execute | SKIP - print command |
| Write code changes | Execute | SKIP - print diff |
| Create PR | Execute | SKIP - print PR body |
| Merge PR | Execute | SKIP |
| Create RCA | Execute | SKIP - print content |
| Close issue | Execute | SKIP |
Dry run output format:
[DRY-RUN] Would execute: gh issue edit 278 --add-label "severity:high,area:aperture"
[DRY-RUN] Would create file: docs/plans/2026-01-28-fix-278-aperture.md
[DRY-RUN] Content:
---
{file content here}
---
To test: /bug-fix 278 --dry-run
gh issue view {issue_number} --repo wellmadetech/m360web --json title,body,labels,comments,state
Create .bug-fix/state.json:
{
"issue_number": {issue_number},
"repo": "wellmadetech/m360web",
"original_text": "{VERBATIM_ISSUE_BODY}",
"current_phase": "triage",
"phases": {}
}
CRITICAL: Save original_text verbatim. Never modify it.
Extract from body:
| Condition | Severity |
|---|---|
| Data loss, security, production down | critical |
| Core feature broken, no workaround | high |
| Feature broken, workaround exists | medium |
| Minor UI, edge case | low |
If issue lacks details:
"Issue lacks reproduction steps. Options: (1) Request more info via comment, (2) Attempt discovery. Choose?"
Update state:
"phases.triage": {
"status": "done",
"affected_area": "{AREA}",
"severity": "{SEVERITY}",
"has_repro_steps": true|false
}
Read references/url-map.json to get:
_base_urls.staging - Main staging URL_base_urls.pr_preview - PR preview URL patternaperture.main → /aperture)Priority order:
_base_urls.staging from url-map.jsonIMPORTANT: Do NOT guess staging URLs. Always read from references/url-map.json.
mcp__plugin_playwright_playwright__browser_navigate url={BASE_URL}{PATH}
If login screen appears (magic link flow):
Ask user for email:
"Authentication required. What email should I use for the magic link?"
(Default suggestion from _auth.suggested_email in url-map.json)
Request magic link:
Prompt user for link:
"Magic link sent to {email}. Please check your email and paste the link here:"
Navigate to magic link URL:
mcp__plugin_playwright_playwright__browser_navigate url={PASTED_LINK}
Verify authentication:
Note: This requires two user interactions: (1) provide email, (2) paste magic link.
For each step:
mcp__plugin_playwright_playwright__browser_take_screenshot.bug-fix/screenshots/step-{N}.pngConsole messages (all levels):
mcp__plugin_playwright_playwright__browser_console_messages level="debug"
Network requests (include failures):
mcp__plugin_playwright_playwright__browser_network_requests includeStatic=false
Look for:
Note what would help future debugging:
Decision Point (failed 3x):
"Cannot reproduce after 3 attempts. Options: (1) Escalate to reporter, (2) Try different environment, (3) Mark as cannot-reproduce. Choose?"
Update state:
"phases.reproduction": {
"status": "done",
"attempts": 2,
"reproduced": true,
"screenshots": ["step-1.png", "step-2.png"],
"console_errors": [...],
"network_failures": [...],
"observability_gaps": ["No click tracking on sidebar"]
}
IMPORTANT: Update the issue title AND body directly, not just add a comment.
Create a clear, descriptive title:
gh issue edit {issue_number} --title "{AREA}: {CLEAR_DESCRIPTION} (was: {ORIGINAL_TITLE})"
Example:
Replace the body with structured content while preserving the original:
gh issue edit {issue_number} --body-file .bug-fix/issue-body.md
The body should include:
<details> block (verbatim from state)Use templates/issue-update.md as the body template.
gh issue edit {issue_number} --add-label "severity:{SEVERITY},area:{AREA},type:bug"
Note: If labels don't exist in the repo, skip this step.
If additional context is needed beyond the body update:
gh issue comment {issue_number} --body "Additional diagnostics: ..."
Update state:
"phases.issue_update": {
"status": "done",
"title_updated": true,
"body_updated": true,
"labels_added": ["severity:high", "area:aperture", "type:bug"]
}
Based on affected area, find:
Use references/url-map.json and references/selectors.json for hints.
# Find relevant files
Grep pattern="{COMPONENT_NAME}" path="src/web"
Grep pattern="{API_ENDPOINT}" path="src/api-nest"
# Read and trace
Read file_path="{FILE}"
Look for:
List all files that need changes:
"phases.investigation": {
"status": "done",
"root_cause": "Missing onClick handler on sidebar product cards",
"affected_files": [
"src/web/src/features/aperture/ImageViewer.tsx",
"src/web/src/features/aperture/components/ProductSidebar.tsx"
],
"missing_error_handling": ["ProductSidebar.tsx:45 - no error boundary"]
}
Path: docs/plans/{YYYY-MM-DD}-fix-{issue_number}-{slug}.md
Include:
If fix spans multiple services (web, api-nest, api):
Update state:
"phases.planning": {
"status": "done",
"plan_file": "docs/plans/2026-01-28-fix-278-aperture-redirect.md",
"implementation_issues": [],
"services_affected": ["web"]
}
git worktree add ../m360web-fix-{issue_number} -b fix/{issue_number}-{slug}
cd ../m360web-fix-{issue_number}
FOLLOW THIS CYCLE EXACTLY:
┌─────────────────────────────────────────────────┐
│ IMPLEMENTATION REVIEW CYCLE │
├─────────────────────────────────────────────────┤
│ 1. Write fix code │
│ 2. Codex CLI review (`codex review`) │
│ 3. Fix Codex issues │
│ 4. Claude review (code patterns) │
│ 5. Fix Claude issues │
│ 6. Codex review (second pass) │
│ 7. Claude review (second pass) │
│ 8. Greptile skill (`/review-pr` local) │
│ 9. Fix Greptile skill issues │
│ 10. Local E2E test (`npm run test:headed`) │
│ 11. ──► If issues, repeat from step 1 │
│ 12. Push PR │
│ 13. Wait for deployment │
│ 14. Check Railway deployment logs │
│ 15. Check E2E CI logs │
│ 16. Wait for Greptile GitHub app review │
│ 17. Respond to Greptile app comments │
│ 18. Respond to all other PR comments │
│ 19. Resolve all conversations │
│ 20. ══► STOP: Wait for human PR review │
│ 21. After approval: Merge │
└─────────────────────────────────────────────────┘
Codex review:
codex review
Claude review: Self-review for:
Local E2E:
cd src/web && npm run test:headed
gh pr create --title "fix(area): description (#issue_number)" \
--body "Fixes #issue_number\n\n## Summary\n{SUMMARY}\n\n## Test plan\n- [ ] E2E passes\n- [ ] Manual verification"
# Wait for deployment
gh pr view {PR#} --json statusCheckRollup
# Check Railway logs
railway logs --build
# Check E2E CI
gh run list --workflow=e2e.yml --limit=1
After push, Greptile GitHub app reviews automatically.
STOP HERE. DO NOT PROCEED UNTIL HUMAN APPROVES.
"PR #{PR_NUMBER} ready for human review. Waiting for approval before merge."
Update state:
"phases.implementation": {
"status": "awaiting_review",
"prs": [{"service": "web", "number": 290}],
"review_cycle": {
"iteration": 1,
"codex_review_1": "done",
"claude_review_1": "done",
"codex_review_2": "done",
"claude_review_2": "done",
"greptile_skill": "done",
"local_e2e": "done",
"pushed": true,
"deployment_logs_checked": true,
"ci_e2e_checked": true,
"greptile_app_review": "done",
"comments_resolved": true,
"human_review": "pending"
}
}
gh pr merge {PR#} --squash --delete-branch
Navigate to staging URL and verify bug no longer reproduces:
mcp__plugin_playwright_playwright__browser_navigate url="https://proxy-m360web-pr-{PR#}.up.railway.app{PATH}"
Re-run reproduction steps. Capture "fixed" screenshots.
Path: docs/rca/{YYYY-MM-DD}-issue-{issue_number}.md
Use templates/rca-document.md:
Post FULL RCA text to issue (not just a link):
gh issue comment {issue_number} --body-file docs/rca/{RCA_FILE}
gh issue close {issue_number} --comment "Fixed in PR #{PR_NUMBER}. See RCA above."
Update state:
"phases.verification": {
"status": "done",
"staging_verified": true,
"rca_file": "docs/rca/2026-01-28-issue-278.md",
"rca_comment_posted": true,
"issue_closed": true
}
.bug-fix/state.json in repo root.
Create .bug-fix/state.lock before updates. Remove after.
On skill invocation, check for existing state:
current_phase| Error | Action |
|---|---|
| Issue not found | Exit with error message |
| Cannot reproduce | Escalate after 3 attempts |
| PR CI fails | Fix and re-push (stay in implementation) |
| Deployment fails | Check Railway logs, fix, redeploy |
| Greptile timeout | Proceed, note in state |
# Triage
gh issue view {N} --repo wellmadetech/m360web --json title,body,labels
# Labels
gh issue edit {N} --add-label "severity:high,area:aperture"
# Comment
gh issue comment {N} --body "message"
# PR
gh pr create --title "fix(area): desc" --body "Fixes #N"
gh pr view {N} --json statusCheckRollup
gh pr merge {N} --squash
# Railway
railway logs --build
railway logs
https://proxy-staging-2b4c.up.railway.app (from url-map.json)https://proxy-m360web-pr-{PR#}.up.railway.appreferences/url-map.json - do not hardcode.bug-fix/state.json.bug-fix/screenshots/docs/plans/docs/rca/