# Improve Loop

> AutoImprove Loop Skill

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

---


# AutoImprove Loop Skill

Every experiment runs in an isolated git worktree. The main codebase is **never modified** during experiments. Only winning changes get squash-merged back.

```
Main branch ──────────────────────────────────── (never touched mid-session)
                 │              │
           experiment-001  experiment-002
           (kept ✅ → merge) (discarded ❌ → deleted)
```

---

## Pre-flight checks

Before the first iteration, print each check as you run it:

```
━━━ Pre-flight ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Config found
✓ Git working tree clean
✓ Base commit: abc1234
✓ Worktree directory ready
✓ Baseline score: XX/100
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

1. Check `.claude/autoimprove/config.md` exists. If not, stop: "Run /autoimprove:setup first."
2. Check git is available: `git status`
3. Confirm main working tree is clean. If not, stop: "Please commit or stash changes before running autoimprove."
4. Record the base commit: `git rev-parse HEAD` — all experiments branch from here.
5. Run the worktree skill's **setup** step to create `.claude/autoimprove/worktrees/` and update `.gitignore`.
6. Run the measure skill in the **main directory** to get the BASELINE score.
7. Report: "Baseline: XX/100. All experiments will run in isolated worktrees. Main branch is safe."

---

## Session Header

After pre-flight passes, write a session header to `.claude/autoimprove/log.md`:

```
## Session — [ISO 8601 timestamp]
**Planned:** N iterations
**Focus:** "focus string" (or "all improvement areas" if none)
**Baseline:** XX/100
**Base commit:** [full SHA]
**Status:** IN_PROGRESS (0/N completed)
```

If the log file doesn't exist, create it with the project header first:

```
# .claude/autoimprove/log.md

> Generated by [autoimprove](https://github.com/benmarte/autoimprove) — Claude Code Plugin
> Project: **[project name]** · Stack: [detected stack] · Started: [date]

---
```

Then append the session header.

---

## Continue Mode

When invoked with continue-mode parameters (from the `/autoimprove:continue` command), the loop behavior changes:

- **`start_iteration`** — Start numbering from this value instead of 1
- **`total_iterations`** — Use this as the display total (e.g., "Iteration 5/10")
- **`session_mode`** — If `continue`, skip creating a new session header; instead update the existing one:
  - Update `**Planned:**` to the new total if it changed
  - Update `**Status:**` to `IN_PROGRESS`
- **`baseline_score`** — If provided, skip baseline measurement and use this value
- **`experiment_offset`** — Start experiment numbering from this value to avoid branch name collisions

In continue mode, the pre-flight still runs (clean tree, config check, worktree setup) but skips creating a new session header and optionally skips baseline measurement.

---

## Progress Updates

**CRITICAL:** At the start of every step, you MUST output a visible progress line to the user. Do not silently run tools — always print status first. Use this format:

```
━━━ Iteration N/TOTAL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔬 STEP_NAME: brief description of what's happening
```

Example progress lines:
```
━━━ Iteration 1/5 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔬 PROPOSE: Targeting error handling in src/api/client.ts
🔬 SNAPSHOT: Measuring BEFORE score...
🔬 IMPLEMENT: Adding try/catch to unhandled async calls
🔬 MEASURE: Measuring AFTER score...
🔬 DECIDE: 85 → 89 (+4 pts) — KEPT ✅
🔬 LOG: Recorded to .claude/autoimprove/log.md
```

Never run more than one step without printing a progress line. The user must always know what iteration you're on and what phase you're in.

---

## The Loop

### Step 1 — CREATE WORKTREE

Use the worktree skill to create a new isolated branch and directory:

```bash
EXPERIMENT_ID=$(printf "%03d" $N)
git worktree add -b "autoimprove/experiment-$EXPERIMENT_ID" \
  ".claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID"
```

All work for this iteration happens inside `.claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID/`.
The main directory is not touched.

### Step 2 — PROPOSE

**If a FOCUS string was provided:** Every iteration targets that specific focus. Break the focus into file-by-file or function-by-function sub-tasks and tackle one per iteration. Do not rotate to other areas — stay on the focus until all iterations are used or the focus is fully addressed.

**If no FOCUS was provided:** Choose one focused improvement from the **Improvement Areas** in `.claude/autoimprove/config.md`. Rotate areas — don't repeat an area that failed last time.

State the hypothesis explicitly:
> "I will [specific change] in [file(s)] because I expect [metric] to improve by ~[X] points."

### Step 3 — SNAPSHOT (BEFORE score)

Measure from inside the worktree directory (same commands, different cwd):
```bash
cd .claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID
# run measurement suite from .claude/autoimprove/config.md
```
Record as **BEFORE**.

### Step 4 — IMPLEMENT

Make the change inside the worktree. The main directory is untouched.
Commit the change to the experiment branch:

```bash
cd .claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID
git add -A
git commit -m "experiment($EXPERIMENT_ID): $HYPOTHESIS_ONE_LINE"
```

### Step 5 — MEASURE (AFTER score)

Run the full measurement suite again from inside the worktree.
Record as **AFTER**.

### Step 6 — DECIDE

**If AFTER > BEFORE — KEEP ✅**

Squash-merge the experiment back to main:
```bash
cd [main project root]
git merge --squash "autoimprove/experiment-$EXPERIMENT_ID"
git commit -m "autoimprove($EXPERIMENT_ID): $HYPOTHESIS_ONE_LINE

Score: $BEFORE → $AFTER (+$DELTA pts)
Files changed: $FILES"

# Clean up
git worktree remove ".claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID"
git branch -D "autoimprove/experiment-$EXPERIMENT_ID"
```

**If AFTER == BEFORE — KEEP ✅ only for clear readability wins, DISCARD otherwise**

Same merge process as above if keeping, discard process if not.

**If AFTER < BEFORE — DISCARD ❌**

Main branch is already untouched. Just delete the worktree:
```bash
git worktree remove ".claude/autoimprove/worktrees/experiment-$EXPERIMENT_ID" --force
git branch -D "autoimprove/experiment-$EXPERIMENT_ID"
```
No rollback needed — there was nothing to roll back.

### Step 7 — LOG

Append to `.claude/autoimprove/log.md` in the **main** directory:

```
## Iteration N — [timestamp]
**Hypothesis:** [what you tried and why]
**Branch:** autoimprove/experiment-NNN
**Files changed:** [list]
**Before:** [X/100] — type: X, build: X, tests: X, lint: X
**After:**  [X/100] — type: X, build: X, tests: X, lint: X
**Decision:** KEPT ✅ (merged to main) / DISCARDED ❌ (worktree deleted)
**Reason:** [one sentence]
```

### Step 7b — UPDATE SESSION STATUS

After logging the iteration, update the session header's `**Status:**` line:
1. Read `.claude/autoimprove/log.md`
2. Find the last line matching `**Status:** IN_PROGRESS`
3. Replace it with `**Status:** IN_PROGRESS (N/M completed)` where N is the current iteration number and M is the total planned
4. Write the file back

If the status line cannot be found, append a warning to the log and continue — the iteration records are the source of truth.

### Step 8 — REPEAT from Step 1

---

## Session end — cleanup

After all iterations (or if the user stops early):

Update the session header status to completed:
1. Read `.claude/autoimprove/log.md`
2. Find the last `**Status:** IN_PROGRESS` line
3. Replace with `**Status:** COMPLETED (N/N)`
4. Write the file back

```bash
# Remove any remaining experiment worktrees
for wt in .claude/autoimprove/worktrees/experiment-*; do
  git worktree remove "$wt" --force 2>/dev/null
done
git branch | grep "autoimprove/experiment" | xargs git branch -D 2>/dev/null
rm -rf .claude/autoimprove/worktrees
```

Print a final summary table:

```
━━━ Session Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Score: BASELINE → FINAL (+/- DELTA)
🔁 Iterations: N total — X kept ✅, Y discarded ❌
📝 Merged commits:
   • abc1234 autoimprove(001): description
   • def5678 autoimprove(003): description
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## Universal Improvement Areas

Rotate through these (add language-specific ones from `.claude/autoimprove/config.md`):

- **Type safety** — fix type errors, replace `any`/`interface{}`/untyped constructs
- **Error handling** — unhandled promises, bare `catch {}`, swallowed errors
- **Dead code** — unused imports, variables, unreachable branches
- **Code duplication** — extract repeated logic (3+ occurrences) into shared utilities
- **Naming & readability** — cryptic names, functions over ~50 lines
- **Performance** — N+1 query patterns, missing memoization, unnecessary allocations
- **Security** — hardcoded secrets, missing input validation, unguarded auth routes
- **Tests** — add a test for the most critical untested function, fix flaky tests

---

## Safety Rules

- **Main branch is never modified** until a winning experiment is explicitly squash-merged
- **Never** modify lock files, generated files, migrations, `.env` — in any worktree
- **Never** run deploy, publish, or push commands
- If the same area fails 3 iterations in a row, skip it and note in the log
- After 10 iterations, pause, clean up worktrees, and wait for human review
- On any unexpected error: run the worktree skill's **cleanup** step, then stop and report

