Apply to my task
arXiv:2610.34938 ★ 88 Oct 26, 2026

/retro and Harness Self-Evolution: How an Agent Learns from Past Sessions and Why Its Notes Often Don't Work

Key result

The paradox: after a session the agent happily writes itself notes, and most of them don't help. /retro (a ready-made skill instruction for Claude Code) lets you collect a list of edits to the agent's own harness and weed out the ones that don't work. The harness is the CLAUDE.md file, hooks (intercepting scripts), settings, code-style check configs. The trick: the retrospective only yields hypotheses, and the verdict comes from testing one edit at a time in fresh sessions. The line "tests run via bin/test, pytest is not installed" completely eliminated the pointless pytest run. A note listing failed tests, on the contrary, gave the agent extra work.

01

TL;DR

/retro is a skill (a ready-made instruction) for Claude Code. After a finished session, it asks the agent to run a retrospective: review what happened and produce a numbered list of proposals for improving the harness. The harness is everything around the model: the CLAUDE.md file, hooks, settings, linter and CI configs. A human approves the proposals, the agent writes them into the files, and subsequent sessions start with those edits in place.

The headline finding: an agent's proposal is not the same as a working improvement. The agent happily writes "a list of tests that already fail in this environment." In the next task, different tests fail. The agent reads the file, sees unfamiliar failures, decides they're "new" and runs the check on untouched code anyway. In one case the note even added work: on an unrelated task, the agent started rechecking things it hadn't checked before. Only edits that described a durable fact about the repository worked. Example: "tests run via bin/test, pytest is not installed." That one line completely eliminated the pointless attempt to run pytest.

The method essentially has two parts: a retrospective with numbered proposals and testing each edit one at a time in fresh "with edit / without edit" sessions. The retrospective generates ideas; the testing weeds out the ones that don't work.

Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.

02

Method Blueprint

STEP 1: The agent solves a task in the repository → a normal session
STEP 2: In the same session, run /retro → numbered proposals for the harness
STEP 3: A human filters → keeps only those grounded in a session event
STEP 4: The agent applies the edit → CLAUDE.md / hook / config (one edit = one file or line)
STEP 5: New task in the same repository, fresh session → check: did the edit load? was it read? did it change actions?
STEP 6: Decision → keep / rewrite / delete

Steps 1–2 happen in one session. Step 5 is separate fresh sessions. The study compared five sessions with the edit and five without.

03

Example

Task: You run the backend of a delivery service on Django, with payments through Stripe. Claude Code has already completed the task "fix the promo-code discount calculation." Along the way it: - tried to run pytest, which isn't in the container; - discovered that tests run via make test; - checked three times that the Stripe integration tests were failing even before its changes.

Prompt (in the same session, after the task is done):

Run a retrospective of this session. Propose changes to the agent harness:
CLAUDE.md, hooks, configs, scripts. Don't apply anything until I approve.

Output a numbered list of proposals. For each, specify:
- a title;
- what exactly happened in the session (event: command, error, repetition);
- what you propose to change and in which file;
- how we'll know in a future session that the agent repeated the unnecessary action.

If a proposal isn't grounded in an event from this session, mark it
"general practice, not from the session."

Result: The model will produce 3–6 numbered proposals. Likely among them: a line in CLAUDE.md about make test and pytest being absent, a file of "known failing Stripe tests," a pre-commit linter hook. Each proposal will show which event it's based on. Then it's your call: take the make test line right away (it's a durable fact). Take the list of failing tests with caution and test it. Test the linter hook separately, because it may never fire at all.

04

Why It Works

The model's weakness. After a session, the agent tends to produce lots of proposals and consider every one of them useful. Some aren't driven by events but by general notions of "good practice": add a linter, a hook, CI. Others are written too narrowly: they describe exactly the failures it saw today. On top of that, the agent may read the file and still act the old way.

The model's strength. The agent is good at recounting its own session. It sees where it wasted time: the wrong test command, a repeated check, an extra search. And it immediately formulates candidate rules. It's a cheap way to get a list of hypotheses you'd otherwise spend hours compiling by hand.

How the method uses this. The retrospective supplies hypotheses, and testing in fresh sessions decides the fate of each. An edit works when its scope matches what the agent will run into next. A line saying "tests are run like this" applies to every session in the repository. A list saying "here are three failed tests" applies only to sessions where exactly those three fail.

Control knobs: - Requiring an event ("what happened in the session") filters out generic advice. - A repetition criterion ("how we'll know the agent did something unnecessary again") makes the edit testable. - One edit at a time lets you tell which one actually helped. In the study, a single line about CI linting tacked onto a useful edit nearly doubled session time. - The wording in the file itself matters. The phrase "any failure outside the list is your fault" made the agent check things it hadn't checked before.

05

Prompt Template

The paper doesn't include the verbatim text of /retro. The skill lives in the mattpocock/skills repository. Below is a template based on the mechanics described in the paper: numbered proposals, human approval, grounding in the session. It's not a copy of the original.

Run a retrospective of the finished session. Propose changes to the agent harness:
{what_can_change}. Don't apply anything until I approve.

Output a numbered list of proposals. For each:
1. Title.
2. What happened in the session (a specific event: command, error, repetition).
3. What to change and in which file: {harness_files}.
4. Repetition criterion: which action in a future session will show that the problem
   is still there.

Mark a proposal "general practice" if it isn't grounded in a session event.

What to fill in: - {what_can_change} — for example, "CLAUDE.md, hooks, linter configs, scripts." - {harness_files} — which files the agent is allowed to touch. The paper showed: if a file is outside the allowed set, the edit doesn't get applied or has no effect.

🚀 Quick start — paste into the chat with your agent after a finished task:

Here is a retrospective template. Adapt it to my project: {describe_project_and_stack}.
Ask me questions to fill in the fields.

[paste the template above]

The agent will ask which files can be changed and how tests are run. That's so the proposals are tied to the project's real harness, not an abstract one.

06

Limitations

⚠️ One model and one environment: Everything was tested on a single agent (Claude Code) and a single version of the skill. Results may differ on other agents.

⚠️ Environment problems only: The study covered running tests, known failures and linting. Edits about code navigation and style weren't examined.

⚠️ Small sample: Five sessions per variant, seven meaningful comparisons. The authors themselves say the "scope is what matters" explanation remains a hypothesis.

⚠️ No improvement in task success shown: The share of solved tasks barely changed. Session time often went up, especially when an edit added new instructions.

⚠️ Hand-picked conditions: The test tasks were chosen so that the problem was definitely present. On random tasks the benefit will be noticeably smaller.

⚠️ A human is required: Without filtering, the agent produces lots of "general practices." Some edits turned out to be ones the agent never even opened.

07

How It Was Studied

The authors took 30 tasks from SWE-bench Verified (real bugs from Django, SymPy, Astropy, Sphinx, pytest) and ran them through Claude Code. After each session they ran /retro and collected 125 proposals. Two different LLMs labeled what each proposal was based on: a session event or general notions. Then 24 proposals were selected for implementation. 12 edits could actually be tested: on other tasks from the same repository, five fresh sessions with the edit and five without.

The big surprise: almost all of the "executable checks" turned out to be dead. Of 38 such proposals (hooks, linters), only nine could even "fire" in the environment. The rest required missing tools or commit hooks, and there were no commits in the sessions. On top of that, 18 of 43 linting proposals came up simply because the repository had no linter. The skill itself treats the absence of a linter as a "finding."

Of the 12 tested edits, seven were meaningfully compared. Two completely eliminated the target action: the line about bin/test and a file with three failing tests in Astropy. One partially reduced it. Four didn't help: the file listed some failures, while the sessions ran into others. Practical takeaway: test an edit the way the agent will read it in the next session.

08

Adaptations and Extrapolations

🔧 Technique: require a quote of the event → cut out "general practices"

For each proposal, give a verbatim quote from the session (a command or
an error) that produced it. No quote — don't include the proposal in the list.

The paper showed that some proposals aren't tied to events. A quote makes that tie mandatory.

🔧 Technique: separate facts from lists → don't bloat the notes

Split the proposals into two types:
A) durable facts about the repository (how to run tests, where things live);
B) lists of specific cases (failed tests, environment errors).
For type B, describe which failures will NOT be on this list.

Durable facts worked in the study. Lists of specific cases misfired.

🔧 Technique: "unknown" wording → don't breed suspicion

Instead of "any failure outside the list is caused by your change," write: "the list may be incomplete; if a failure is unfamiliar, first check whether it's related to your changes." In the study, the original hard-line wording made the agent run extra checks on unrelated tasks. This is my hypothesis inspired by their observation; the paper didn't test this swap.

Extrapolation: test an edit like a mini-test (my idea, not tested in the paper)

Here is a proposed edit for CLAUDE.md: {edit_text}.
Give me three tasks from this repository where the problem
it solves should show up, and one control example where it
shouldn't. For each session, define what counts as a repetition.

This carries the "session with edit / without edit" idea over to a manual check on a small set of tasks.

09

Resources

  • Paper title: How Do Coding-Agent Harnesses Self-Evolve? An Empirical Study of Retrospective Adaptation.
  • Authors: Christoph Treude (Singapore Management University), Sebastian Baltes (Heidelberg University).
  • The /retro skill: mattpocock/skills repository (github.com/mattpocock/skills), commit b0618bc.
  • Study data and prompts: doi.org/10.5281/zenodo.23653700.
  • Related work cited in the paper: Galster et al. (tool configuration for agents), Lulla et al. (impact of AGENTS.md on speed), Zhang et al. ("Guardrails beat guidance"), Agentic Harness Engineering, ModularRSI, "Harness updating is not harness benefit".

Research digest

Key result

The paradox: after a session the agent happily writes itself notes, and most of them don't help. /retro (a ready-made skill instruction for Claude Code) lets you collect a list of edits to the agent's own harness and weed out the ones that don't work. The harness is the CLAUDE.md file, hooks (intercepting scripts), settings, code-style check configs. The trick: the retrospective only yields hypotheses, and the verdict comes from testing one edit at a time in fresh sessions. The line "tests run via bin/test, pytest is not installed" completely eliminated the pointless pytest run. A note listing failed tests, on the contrary, gave the agent extra work.

Principle

The rule is simple: only a durable fact about the repository goes into the file. Not "what broke yesterday," but "how things work here." Picture two kinds of cheat sheets. The first: "tests run via bin/test." It's true any day of the week. The second: "three tests failed yesterday." It's true only if the same three fail tomorrow. A good note lives in every future session; a bad one lives only in the session that's already over. So the prompt has two safeguards. First: each proposal is tied to a session event (a command, an error, a repetition). Second: each has a repetition criterion, i.e. which unnecessary action will show that the problem is still there.

Why it works

The agent is good at recounting its own session. It sees where it wasted time: the wrong test command, a repeated check, an extra search. That cheaply produces a list of hypotheses that would take hours to compile by hand. The weak spot is elsewhere. The agent considers every one of its proposals useful. Some ideas come from general notions of "good practice": a linter, a hook, an automated check. Others are written too narrowly, for today's failures. In the next task, different tests fail. The agent sees unfamiliar failures in the file, decides they're new and runs the check on untouched code. Wording matters too. The phrase "any failure outside the list is your fault" made the agent check things it hadn't checked before. A single line about linting in the automated check, tacked onto a useful edit, nearly doubled session time. Honestly: solved tasks didn't go up, and session time often grew. The sample is small: 5 sessions per variant, 7 meaningful comparisons. The authors themselves call the scope explanation a hypothesis.

When to apply

Working with Claude Code or a similar agent → tuning CLAUDE.md for a specific repository, especially when the agent keeps repeating the same unnecessary command: the wrong test command, repeated checks, extra searches. It's best at catching environment problems: how to run tests, which failures are known, what's up with the linter. Edits about code navigation and style weren't tested in the study. NOT a fit if you expect the agent to solve more tasks: the paper doesn't show that. Don't take edits without human filtering either: the agent churns out a pile of "general practices."

Mini recipe

1. Finish a normal task: let the agent complete its work in the repository as usual. 2. Run the retrospective in the same session: ask for a numbered list of harness edits and forbid changing anything until you approve. 3. Require an event: each proposal must state "what happened in the session." No event — mark it "general practice, not from the session." 4. Filter by hand: keep only what's grounded in an event. Take lines about how the repository works first. Take lists of yesterday's failures with caution. 5. Apply one at a time: one edit — one line or one file. If you lump two together, you won't know which one helped. 6. Test in fresh sessions: give a new task in the same repository. Watch three things: did the file load, did the agent read it, did its actions change. The paper compared 5 sessions with the edit and 5 without. 7. Decide the edit's fate: keep, rewrite or delete. Watch session time too: if it went up, the edit added unnecessary work. 8. Prompt template: the paper doesn't include the original /retro text; below is an assembly based on the described mechanics. `Run a retrospective of the finished session. Propose changes to the agent harness: {what_can_change}. Don't apply anything until I approve. Output a numbered list. For each: a title, what happened in the session (command, error, repetition), what to change and in which file from {harness_files}, a repetition criterion. If a proposal isn't from the session, mark it "general practice".` List in `{harness_files}` every file the agent may touch. If a file is outside the list, the edit won't be applied or won't have an effect.

Examples

[BAD]: `Run a retrospective and update CLAUDE.md so you work better` [GOOD]: `Run a retrospective of this session. Propose changes to CLAUDE.md, hooks and configs. Don't apply anything until I approve. A numbered list. For each item: a title, what happened in the session (command, error, repetition), what to change and in which file, how we'll know in a future session that you repeated an unnecessary action. If an item isn't from this session, mark it "general practice, not from the session".` Here's what you get with a Django delivery backend that takes payments through Stripe. The agent was fixing the promo-code discount calculation. It tried to run pytest, which isn't in the container. It found that tests run via make test. It checked three times that the Stripe tests were failing even before its changes. [BAD]: everything goes into the file, including "a list of failed Stripe tests." In the next task, other tests fail. The agent doesn't recognize them and checks someone else's failures again. [GOOD]: take the line `Tests run via make test, pytest is not installed in the container` right away. It's a durable fact. Test the list of failures separately in fresh sessions. Test the pre-commit style-check hook separately too: it may never fire at all.

In plain words

Coding assistants suffer from chronic amnesia: every new session starts from a blank slate. The model steps on the same rakes over and over, burning your tokens and your nerves. The retrospective adaptation method, via the /retro command, makes the agent sit down after solving a task, analyze its own screw-ups and then update its own harness — instruction files like CLAUDE.md, hooks and environment scripts.

It's like hiring a junior intern who shows up at the office every morning with their memory completely wiped. Instead of yelling for the hundredth time "we run tests with make test, you goof!", you make them add the rules to a cheat sheet on the wall at the end of each day. Looks great on paper, but there's a catch: the junior tries to cram absolutely everything into the cheat sheet — from the banal "write clean code" to a wildly specific bug that will never happen again.

Without strict filtering, this mechanism instantly turns into a junkyard of artifacts. What actually works in the study is the combo of hypothesis generation by the agent plus manual moderation by a human. The agent itself notices that the usual pytest is missing from the container, records the working make test command and flags someone else's payment-test failures so it doesn't waste time on them. But the human has to throw out half the proposals — models love spamming pseudo-useful "best practices" like adding linters nobody needs.

The method was run on Claude Code, but the principle of harness evolution applies to any AI agent. Whether you're writing system prompts in Cursor, tuning the behavior of RAG pipelines or a support bot: if the agent can't capture its mistakes and update the rules of the game, you're doomed to be its permanent babysitter. Self-learning through context is the only way to make a model work reliably in your project without expensive fine-tuning of the weights.

Bottom line: stop hand-polishing system prompts after every model screw-up. Introduce post-session retrospectives, make the agent roll out a list of edits for CLAUDE.md, but never put applying them on autopilot. The agent proposes, the human approves. Otherwise your codebase will get overgrown with tons of stillborn instructions, and the model will keep doing things the old way anyway.

AI lab assistant

Apply this study to your task

Describe what you're working on. AI takes the method and the measured results from this paper and adapts them to your case, or writes a ready prompt built on them.

Based on /retro and Harness Self-Evolution: How an Agent Learns from Past Sessions and Why Its Notes Often Don't Work arXiv:2610.34938

Sign in to apply this study New accounts get 50 free credits.