Claude
Skills
Sign in
Back

iterate

Included with Lifetime
$97 forever

Autonomous improvement loop - modify, measure, keep or discard, repeat. Inspired by Karpathy's autoresearch. Triggers on: iterate, improve autonomously, run overnight, keep improving, autoresearch, improvement loop, iterate until done, autonomous iteration, batch experiments.

Generalscripts

What this skill does


# Iterate - Autonomous Improvement Loop

Inspired by [Karpathy's autoresearch](https://github.com/karpathy/autoresearch): constrain scope, clarify success with one mechanical metric, loop autonomously. The agent modifies code, measures the result, keeps improvements, discards regressions, and repeats - until any stop condition fires or the user interrupts.

The power is in the constraint. One metric. One scope. One loop. Git as memory.

## Preflight

Before the loop starts, do the work that makes the loop effective. Don't skip steps - this discipline is what separates a productive overnight run from a flailing one.

### 1. Collect Config

If provided inline, extract and proceed. If required fields are missing, ask once using `AskUserQuestion` with all missing fields batched together.

| Field | Required | What it is | Example |
|-------|----------|------------|---------|
| **Goal** | Yes | What you're improving, in plain language | "Increase test coverage to 90%" |
| **Scope** | Yes | File globs the agent may modify | `src/**/*.ts` |
| **Verify** | Yes | Shell command that outputs the metric (a number) | `npm test -- --coverage \| grep "All files"` |
| **Direction** | Yes | Is higher or lower better? | `higher` / `lower` |
| **Guard** | No | Command that must always pass (prevents regressions) | `npm run typecheck` |
| **Batch** | No | Changes per iteration. >1 enables bisect-on-regression. Default `1`. | `3` |
| **Iterations** | No | Hard cap on iteration count. | `30` |
| **Until** | No | Stop when metric crosses this target value. | `90` |
| **Stagnation** | No | Stop after N consecutive iterations with no improvement. | `15` |
| **Branch** | No | Branch isolation. `current` (default), `auto` (slug from goal), or explicit name. | `auto` |

**Stop conditions are OR'd**: any combination of `Iterations`, `Until`, `Stagnation` may be set. The loop stops when any one is satisfied. If none are set, the loop is unbounded - it runs until interrupted.

### 2. Plan

Read all in-scope files. Understand the codebase before touching anything.

- What's the current state? What's already been tried?
- What are the likely improvement vectors? Rank them.
- What are the risks? What could break?
- Form a rough strategy for the first 5-10 iterations.

### 3. Permissions

Check that `allowed-tools` cover what the loop needs. The verify and guard commands must run without permission prompts - a blocked tool at 3am kills the whole run.

- Dry-run the verify command. If it gets blocked, note which `Bash(command:*)` pattern is needed.
- Dry-run the guard command (if set). Same check.
- If permissions are missing, suggest specific wildcard additions for `.claude/settings.local.json` and ask the user to approve before starting. Reference `/setperms` for a full setup.

### 4. Branch Setup

The `Branch` field controls where iteration commits land.

| Value | Behavior |
|-------|----------|
| `current` (default) | Stay on the current branch. Commits land directly. |
| `auto` | Create `iterate/<slug-from-goal>` from current HEAD and switch to it. |
| `<explicit-name>` | Create branch with that exact name and switch to it. |

**Slug derivation** (for `auto`): lowercase the Goal, replace non-alphanumeric runs with `-`, trim leading/trailing dashes, truncate to 40 chars. "Increase test coverage to 90%" → `iterate/increase-test-coverage-to-90`.

**Collision**: if the branch already exists, suffix `-2`, `-3`, etc.

**Confirm before switching**: print the chosen branch name and source branch. Do not silently create a branch the user didn't ask for.

**Cleanup**: never auto-delete the branch. The user decides whether to merge, open a PR, or `git branch -D` it. The skill's job ends at "branch exists with results."

### 5. Tasks

Create a TaskList to track progress across iterations. This provides structure the user can check without reading the full results log.

```
TaskCreate: "Establish baseline" (status: in_progress)
TaskCreate: "Iteration loop - [goal]" (status: pending)
TaskCreate: "Final summary and cleanup" (status: pending)
```

Update task status as the loop progresses. Mark the iteration task as `in_progress` when the loop starts, `completed` when it ends.

### 6. Tests and Verification

Before the first iteration, make sure verification actually works:

- Run the verify command on the current state. If it fails or produces no parseable number, fix this first.
- Run the guard command (if set). If it fails on the current state, the codebase has pre-existing issues - flag to the user.
- If tests don't exist yet for the scope, consider writing them as iteration 0. Good tests make the loop more effective.

### 7. Baseline

Record the starting point:

1. Run verify command, extract the metric - this is iteration 0
2. Create `results.tsv` with the header and baseline row
3. Tag the baseline: `git tag iterate/best` (will float forward as the metric improves)
4. Update the baseline task to `completed`
5. Confirm setup to the user, then begin the loop

```
Goal:        Increase test coverage to 90%
Scope:       src/**/*.ts
Verify:      npm test -- --coverage | grep "All files"
Direction:   higher
Guard:       npm run typecheck
Branch:      iterate/increase-test-coverage-to-90 (created from main)
Batch:       3
Stop:        Iterations 50 OR Until ≥ 90.0 OR Stagnation 15
Baseline:    72.3
Permissions: verified

Starting iteration loop.
```

## The Loop

```
LOOP (until any stop condition met):

  1. REVIEW    git log --oneline -10 + read results.tsv tail
              Know what worked, what failed, what's untried.

  2. IDEATE    Pick UP TO `Batch` independent changes. Each must stand on
              its own and be applicable independently. Write a one-sentence
              description per change BEFORE touching code. Consult git history -
              don't repeat discarded approaches.

  3. MODIFY+COMMIT
              For each change in the batch (in order):
                a. Apply the change to in-scope files only.
                b. git add <specific files>   (never git add -A)
                c. git commit -m "experiment: <one-line description>"
              Each change is its own commit. Non-negotiable - bisection
              depends on it.

  4. VERIFY    Run the verify command after the final commit of the batch.
              Extract the metric. If guard is set, run it too.

  5. DECIDE
              Improved + guard ok (or no guard)
                -> KEEP entire batch
              Regressed / unchanged / guard failed:
                if Batch == 1 -> REVERT the one commit
                if Batch >  1 -> BISECT (see below)
              Crashed (verify or guard non-zero exit, not just regressed)
                -> attempt fix (max 3 tries), else REVERT entire batch

  6. LOG       Append one row per change to results.tsv.

  7. SNAPSHOT  If the new metric beats the previous best, force-update tag:
              git tag -f iterate/best

  8. CHECK STOP
              Iterations cap reached?       -> stop, summarize, exit.
              Until target crossed?          -> stop, summarize, exit.
              Stagnation N reached?          -> stop, summarize, exit.
              Interrupted / fatal error?     -> stop, summarize, exit.

  9. REPEAT    Go to 1. Print a one-line status every 5 iterations.
              NEVER ask "should I continue?" - just keep going.
```

### Bisection (Batch > 1, regression detected)

When a batched verify fails, the loop must identify which commit(s) caused the regression - keeping the good ones, dropping the bad ones.

```
1. Note C0   = the iteration's start commit (before the batch)
   Note C1..CN = the batch commits in order

2. git reset --hard C0

3. For each Ci in order:
     a. git cherry-pick Ci
     b. Run verify
     c. Improved or held + guard ok -> keep (commit stays in history)
        Regressed or guard failed   -> git reset --hard HEAD~1 (drop)

4. Log each change's outcome to results.tsv:
     status=bisect-keep   -> co
Files: 2
Size: 19.6 KB
Complexity: 45/100
Category: General

Related in General