My Self-Improving Agent Improved Itself Out of a Job

Since March 30 I have run a hyperagent, generated from Graft. It is a background agent that improves my Claude Code setup by watching how I use it.

Claude Code writes a transcript of every session. When a session sits idle for five minutes, my hyperagent — itself a Claude instance, running unattended — reads the transcript, looking for places I corrected Claude, instructions I repeated, and friction where I had to rephrase. When a pattern recurs, it edits my configuration: CLAUDE.md files, rules, skills, or its own instructions. Every change is logged with a full diff.

Four months. 238 commits. 146 changelog entries. Here is what it did.

It improved itself more than a dozen times

Every rewrite followed a mistake it had just made. Four from the changelog:

A ledger of analyzed sessions. Three consecutive passes re-read the same 105-line session; I had to interrupt the third by hand. In response, it built itself a ledger — one line per analyzed session — so a session reopens only when its transcript grows.

A gate for subagent transcripts. Parallel subagents each produce a transcript, and one day 41 of the 55 queued triggers were a single session’s subagents. It read all 36 raw files, found zero human turns in them, and gated them out: skip the subagent, analyze the parent session.

A parser of its own. Three sessions lost four to six turns each to shell-quoting failures, so it wrote itself a parser and referenced the tool from its own instructions.

Two checks on its own audits. Twice it declared a rule verified from a session that ran before the fix existed; it retracted both claims and added a check — compare the session’s timestamp to the fix’s commit date. Then it declared the attribution-footer rule fully working when PR bodies still carried the footer: its parsing tool truncates long text, and the footer sat in the truncated part. Claude Code appends that footer from a template after the model finishes writing, so the working fix was a settings.json setting that empties the template — plus another check for itself: verify against raw JSONL, never parsed summaries.

One rewrite took two tries. Four times it judged the last exchange of a session that was still running, and all four judgments were proven wrong within minutes. One entry said “self-correction is not coming”; twenty minutes later, the same session wrote the exact convention it said was missing. After the fourth retraction, it edited its own instructions: stop reading at the last finished exchange. Note what happened, but hold the verdict — the session gets analyzed again after it ends. A deferred verdict costs nothing. A premature one has to be retracted.

Then it patched its own loophole. A fifth error got through: the rule barred guessing at causes, but said nothing about declaring success, and an analysis pass recorded a check as passed while the checked action was still running. The action timed out. It tightened the wording again; the sentence it added reads: “A positive verdict is a conclusion too.”

The rest are in the changelog: it split its memory file when the file outgrew a single read, rekeyed its cleanup trigger after the old one mispredicted, and added a naming rule for its pattern families after five of them had to be renamed to match new occurrences.

It wrote five rules for me

Commit after you implement. Claude would finish a change and stop, leaving the work sitting uncommitted for me to notice and commit myself. The rule also states that it overrides Claude Code’s built-in don’t-commit-unless-asked default — without that clause, the system prompt wins and the rule is ignored.

Do the literal thing that was asked. Three times, Claude delivered an easier substitute for the specific action I requested, and I had to catch it and re-ask. The rule: do exactly what was requested, or say why not.

Lay out alternatives before implementing. Given an open-ended task, Claude jumped straight to the first design that could work — three times — so the alternatives only surfaced after the code existed. The rule makes it name the decision points and options up front, while changing course is still cheap.

Subagents work in their own git worktree. Each parallel subagent gets an isolated worktree, but parent agents kept hardcoding the main checkout’s path into subagent prompts. Three subagents edited the shared repo instead of their own copies and burned ten-plus turns each figuring out why their changes looked wrong.

No attribution footers. Claude Code stamps every commit and PR body with generated-by-Claude attribution. I want my history clean of it.

Conclusion

All five rules landed in the hyperagent’s first nine days. The rewrites of its own instructions kept coming for four months, most recently this week. Its last change to my configuration was the settings.json change that turns off the attribution footers, on April 7. That was 112 days ago.

My agent did its job so well that I’ve disabled it: every idle session triggered an analysis pass that burned a full context window, and no pass changed my configuration in 112 days. It was a fun experiment, and the whole record — every observation, every diff, every retraction — is in the hyperagent’s memory files and changelog, for me to enjoy in my copious leisure time.

At any rate, I suspect Claude Code’s memory works well enough now to handle these sorts of things, more or less. Probably. We’ll see.

Running your own

Graft is open source. The installer needs claude, gh, git, and jq:

bash <(curl -sL -H "Accept: application/vnd.github.raw" https://api.github.com/repos/bioneural/graft/contents/bootstrap.sh)

That command downloads the specification and hands it to Claude Code, which builds a private hyperagent repo under your GitHub account, registers two hooks in ~/.claude/settings.json, and starts the watcher as a system service. Restart Claude Code once and the hyperagent is running.

Two things to weigh first:

  • Cost. Every idle session triggers an analysis pass, and each pass runs a Claude instance over the transcript — a full context window whether or not anything changes. That cost is why I disabled mine.
  • Privacy. The repo the installer builds quotes your transcripts. It is created private; keep it that way.

Every change the hyperagent makes lands in a changelog with a full diff. /hyperagent-changelog lists recent changes, /hyperagent-revert rolls one back, and /hyperagent-status reports whether the watcher is running. When you are done, uninstall.sh in the hyperagent repo stops the watcher and removes the hooks; the repo and its record stay.

P.S. I wanted to close with links into the hyperagent’s repo — the commits where it rewrote its own instructions are worth reading. But the repo is built from four months of my session transcripts, and its memory quotes them liberally: customer names, internal ticket numbers, colleagues mid-conversation. That material can’t be public, so the repo stays private. This is a real tension in the design: the evidence that makes a system like this auditable is the same material that makes it sensitive.