---
name: code-review-fix
description: >
  Run a review-and-fix loop on the current branch: invoke /code-review, fix every issue (including
  minor/nit) with one commit per item, then re-review until zero issues remain (max 5 iterations).
  Use when the user says /code-review-fix, 'review and fix', 'review et corrige', 'boucle de review',
  'review et fix', 'corrige les remarques de review', 'corrige tout ce que la review trouve',
  'relis et corrige mon code', 'review then fix everything', 'fix all the review comments',
  'clean up my changes until they pass review', or when delegated from /code-implement after
  implementation. Distinct from /code-review, which only reviews and reports without changing the
  code — this one applies the fixes and re-reviews until clean.
argument-hint: "[optional: commit prefix e.g. 'fix' or 'feat'] [optional: issue filter — e.g. '#4 uniquement', 'exclu la #3', 'only #1,#2', '--exclude 3,5'] [--skip-approve] [--ask=false|true|auto] [--notify=true|false]"
allowed-tools:
  - Read
  - Edit
  - Write
  - Glob
  - Grep
  - Bash
  - Skill
  - AskUserQuestion
---

Run a review-fix loop on the current branch until **all review issues are fixed** (including minor ones).

## Required tools

- `glab`
- `jq`

Run `pysae-ai-tools tools require <tools>` before starting; if it exits non-zero, abort and report the install command from stderr to the user.

## Step 1 : Detect context

```bash
CTX=$(pysae-ai-tools internal detect-context)
IS_CI=$(echo "$CTX" | jq -r '.is_ci')
MR_IID=$(echo "$CTX" | jq -r '.mr_iid // empty')
ISSUE_IID=$(echo "$CTX" | jq -r '.issue_iid // empty')
```

CI mode (`IS_CI == "true"`): never use `AskUserQuestion` — fail with exit code 1 if issues remain after max iterations.

## Step 2 : Ensure correct working branch

If invoked **directly by the user** (not delegated from another skill): invoke `/git-worktree` to ensure correct branch. Skip if delegated.

## Step 3 : Determine commit prefix

Determine `COMMIT_PREFIX` following [../references/commit-rules.md](../references/commit-rules.md).

## Step 4 : Review loop

### Run review

Always invoke `/code-review` at iteration 1 — even if a previous review note exists on the MR. The local working tree may have changed since that note was posted (new commits, fixes, refactors), so a fresh review is required to surface any new issues.

Invoke `/code-review` to analyze the changes.

**Incremental review (iteration 2+)**: after fixing issues, only the changed files need re-review. Track which files were modified during fixes and pass them as focus scope to `/code-review`:
```
/code-review <space-separated list of modified files>
```
This narrows the review scope and avoids re-analyzing unchanged code.

### Evaluate issues

Collect **all** issues regardless of severity. Each issue is identified by its `\#<N>` from the review output.

**Apply issue filter from `$ARGUMENTS` (iteration 1 only)** — parse natural-language or flag-style filters:

- **Inclusion only** (keep only listed numbers): `#4 uniquement`, `uniquement #1,#3`, `only #2`, `--only 1,3`
- **Exclusion** (skip listed numbers): `exclu la #3`, `sauf #2,#5`, `except #4`, `--exclude 3,5`
- **No filter**: fix every issue, loop until zero remain

Extract the integer list from the filter and intersect/subtract against the collected issues. Print the filter applied (e.g. `Filter: only \#4 — skipping \#1, \#2, \#3, \#5`) before fixing.

**When a filter is applied, perform a single fix pass — do not loop.** The user explicitly opted out of fixing other issues, so re-running `/code-review` and re-fixing the previously excluded issues (which would now be re-numbered) violates intent. After fixing the filtered subset, go straight to Step 5.

**Without a filter**: the loop stops only on **zero issues**.

### Fix review issues

**One commit per review item, in declaration order.** For each issue:

1. Fix the problem
2. Run tests and linters
3. Commit only this fix:
   ```bash
   git add <specific_files>
   git commit -m "$(cat <<'EOF'
   ${COMMIT_PREFIX}: <short description of the change>

   Co-Authored-By: Claude <noreply@anthropic.com>
   EOF
   )"
   ```
4. Do **NOT** push — all commits are pushed once at the end

### Re-review

**Skip this sub-step entirely if a filter was applied at the « Evaluate issues » sub-step.** Otherwise go back to « Run review ». Max **5 iterations**. If issues remain after 5 cycles:
- **Local mode**: ask the user for guidance
- **CI mode**: exit 1 with remaining issues in stdout

Display: `Iteration N` (not `N/5`).

## Step 5 : Final validation

When zero issues, **always execute all sub-steps below** — even if the review was APPROVED on the first iteration with no fixes (i.e. nothing to push). Do NOT skip this step.

1. `git push` (single push for all fixes — no-op if nothing to push, that's fine)
2. **Local mode only, and only when `$ARGUMENTS` does NOT contain `--skip-approve`**: delegate `/glab-mr-approve` (it always attempts the approval and, on any failure — whatever the project's approval rules — falls back to `/slack-ask-review` automatically). **Skip entirely in CI** — never auto-approve in CI. `--skip-approve` is the lever the caller (typically `/code-autopilot` running with `--approve=ask` or `--approve=skip`) uses to keep the approve decision out of this skill. When `$ARGUMENTS` contains `--ask=false|true|auto`, propagate it verbatim to `/glab-mr-approve` so the caller controls the manual-testing prompt (e.g. `/code-autopilot --approve=auto` calls this skill with `--ask=false`). Likewise, when `$ARGUMENTS` contains `--notify=true|false`, propagate it verbatim to `/glab-mr-approve` so the caller controls the post-approve Slack notification (e.g. `/code-autopilot --merge=auto` passes `--notify=false` because it posts its own post-merge summary instead).
3. `pysae-ai-tools glab workflow-transition ${ISSUE_IID} "workflow::Under review"`

$ARGUMENTS
