# Fix Issue

> End-to-end workflow to fix a GitHub issue — collect context, analyze, implement on a branch, open a PR, then hand off to /pr-watch-fix until CI is green.

- Skill: `oxsecurity/fix-issue` (Agent Skill)
- Install (CLI): `npx skillmds@latest add oxsecurity/fix-issue`
- Raw SKILL.md: https://api.skillmd.com/api/skills/oxsecurity/fix-issue/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: oxsecurity (https://skillmd.com/u/oxsecurity)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/oxsecurity/fix-issue

---


Resolve the GitHub issue `$ARGUMENTS` end-to-end.

> **Delegation hints** (token / model optimisation):
> - **Build step**: delegate `make megalinter-build` runs to the `build-runner` agent (haiku).
> - **Version pin edits**: delegate to `version-bumper` (haiku).
> - **CI watching after PR open**: hand off to the `pr-watch-fix` skill (sonnet), which itself delegates polling to `pr-monitor` (haiku).
> - **Security-related issues**: delegate CVE analysis to `security-analyst` (opus) — but you're already on opus, so do it inline if cheaper.

Global git/PR rules (no AI attribution, commit-as-user, no pushes to `main`, no `--force`, stage by path) live in `CLAUDE.md` → **Git & PR Conventions**. Follow them — do not restate them here.

## Step 1 — Resolve the issue

Parse `$ARGUMENTS` (accept `123`, `#123`, `owner/repo#123`, full URL). If empty, ask the user.

```bash
gh issue view <ref> --json number,title,body,labels,state,url,author,comments
```

Read body **and all comments** in full — context often lives in a comment. If the issue is closed, ask before proceeding.

## Step 2 — Gather context

- Linked PRs / prior attempts: `gh issue view <n> --json closedByPullRequestsReferences,timelineItems`
- Grep for any file paths, error strings, linter names, descriptor IDs, env vars mentioned in the issue
- Read the relevant descriptor (`megalinter/descriptors/`), subclass (`megalinter/linters/`), reporter (`megalinter/reporters/`), or fixtures (`.automation/test/`)
- Fetch external links with WebFetch — upstream release notes often contain the fix

## Step 3 — Analyze and propose

Form a concrete hypothesis. **Ask via `AskUserQuestion`** when any of these are true:

- Root cause is ambiguous and you have more than one plausible explanation
- Multiple valid fix approaches with real tradeoffs (descriptor vs. subclass, version bump vs. behavior patch, rename vs. alias)
- The fix touches user-visible behavior (config keys, defaults, output format, env-var semantics)
- It's a feature request whose design isn't already implied by the issue
- You can't reproduce the bug from the description

Present: failing behavior, hypothesis, 2–3 options, recommendation. Include a "stop and let me investigate" option when the cause is unclear.

Skip the question only when the fix is local and obvious.

## Step 4 — Prepare the branch

```bash
CURRENT_BRANCH="$(git branch --show-current)"
DEFAULT_BRANCH="$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)"
```

If `CURRENT_BRANCH` equals the default branch (`main`/`master`/etc.), create `fix/issue-<NUMBER>-<short-slug>` off it. Otherwise keep working on the current branch.

If `git status --short` shows unrelated uncommitted changes, stop and ask.

## Step 5 — Implement

- Descriptor changes → edit YAML, then `make megalinter-build` (NEVER `make megalinter-build-with-doc`)
- Python → see `.claude/rules/python-style.md`
- Never edit files marked `@generated by .automation/build.py` — change the source and rebuild
- Do NOT update `CHANGELOG.md` for CVE ignores or version bumps; for genuine user-facing fixes, add one line under **Fixes** in the beta section, written for end users per `.claude/rules/changelog.md` (what changes for them — no implementation details)
- Run quick local validation (`python -m py_compile`, etc.) — Docker-only checks are left to CI

## Step 6 — Commit

Match the repo's commit style (`git log --oneline -10`). Format:

```text
<type>: <imperative one-line summary> (#<ISSUE_NUMBER>)

<optional body, 1–3 lines>

Fixes #<ISSUE_NUMBER>
```

Use a HEREDOC:

```bash
git commit -m "$(cat <<'EOF'
fix: <summary> (#<N>)

<body>

Fixes #<N>
EOF
)"
```

## Step 7 — Push and open the PR

```bash
HEAD_BRANCH="$(git branch --show-current)"
BASE_BRANCH="$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)"
git push -u origin "$HEAD_BRANCH"
```

Pass `--base` and `--head` explicitly so `gh` never prompts and never picks the wrong target (especially with forks):

```bash
gh pr create --base "$BASE_BRANCH" --head "$HEAD_BRANCH" --title "<title>" --body "$(cat <<'EOF'
## Summary

<2–4 sentences: root cause and how this PR fixes it>

## Changes

- <bullet per meaningful change>

## Test plan

- [ ] <how to verify>
- [ ] <edge cases>

Fixes <ISSUE_URL>
EOF
)"
```

Capture the PR number and URL.

## Step 8 — Hand off to /pr-watch-fix

Invoke `/pr-watch-fix`. It owns the 5-minute polling loop, log inspection, fix-commit-push cycle, bot-rebase handling, and stop conditions.

One nuance to apply before invoking: CI-fix commits should use `Refs #<N>` (not `Fixes #<N>`) so a later squash-merge of a follow-up doesn't prematurely close the issue.

When `/pr-watch-fix` returns, report one line:

- Success: `PR #<N> is green: <url>`
- Stuck: `Stuck on <check>: <root cause>. PR: <url>. Need your input.`

