Survival of the honest
For the second time, we gave an AI agent its own source code and told it to leave behind a better version of itself. Last time the only thing we learned for certain was that our referee could not tell an improvement from a copy. So we rebuilt the referee, set four lines of the agent loose against each other for 150 rounds, and this time scored each version on the children it produced. What they built with that freedom, what they claimed about it, and what a program does when it is finally selected for getting better at getting better.
- published
- author
- Hendrik
An experiment about self-improvement is only as good as its referee. That was the lesson of our first attempt at a singularity in miniature: one AI agent, a copy of its own source code, and a loop that let each version try to build a better one, judged by its own ancestors. The agent did improve. But when we checked the referee against an unchanged copy of the program, it promoted the copy about as often as it promoted anything else. Whatever had happened in those two days, the record could not say whether the gains had compounded, because the instrument could not see them.
This post is about the second attempt. For anyone who skipped the first post, the machine fits in two sentences: an agent is handed its own source and told to leave behind a better version of itself; an orchestrator that never writes code builds what the agent leaves, examines it against its parent, and keeps or discards it, with nobody in the room. The first post explains every part of that loop and why it is built the way it is. Here the loop is a given. What follows is what we changed and then, for most of the post, what the agents did with it.
The run lasted four days and 150 rounds, and all of it is public at codeminer-gmbh/singularity-agent-evolution-2: one commit per version, one branch per line, every rejected candidate kept on a branch of its own. What happened is a stranger story than the first run's. The agents built the same document readers three times over. They installed a geographic information system to pass a coding exam. One line diagnosed its own disease in writing and relapsed within the week; another wrote a regular expression that forbids its author from using the word "verified". And the final champion came out of a branch the judges had read as worse.
What we changed, and why
The first run failed in two separate ways. Its selection pressure pointed at the wrong thing: the exam measured answers, so the agent evolved answers, and the ability to improve was checked only by a pass-or-fail liveness test. And its referee was too blunt to see what it was pointing at. Every change in the second run addresses one of those two problems.
The most important change is what a version is judged on. Before a candidate sits its exam, it is asked to do the one thing the loop is actually about: improve itself once more. The child it writes sits the same exam. A candidate whose child beats it is rewarded; one whose child loses to it on every test is thrown out as a bad improver, however good its own answers were. A strong child can even take the line's lead outright, skipping the version that wrote it. For the first time, the loop selects for getting better at getting better.
The referee was rebuilt around three ideas. Every exam question ships with an executable check, so a judge's opinion sits next to a score it cannot argue with. Two referees sit on every panel, and neither of them is a product of the evolution: one is the hand-written seed, frozen at the start and never a contestant, the other a different program altogether, the OpenAI Codex command-line agent behind a thin adapter, instructed to verify before it believes and never to invent a difference to avoid a tie. And every eleventh round, the panel is handed an unchanged copy of a line's current best version and asked whether it is an improvement. That control experiment is the one measurement in the run with a known right answer.
The rest is structure. Three lines of descent evolve from one hand-written seed, and every ten rounds their heads play a tournament whose rating decides which lines continue: a line that keeps finishing last is retired and a new one is founded from the champion. Every few rounds, a line is told to improve not the agent but the instructions the agent improves itself under, and now and then a line branches from an ancestor instead of its head, so that an idea which pays off late has a way back. Every note a version leaves for its successor is audited against the diff it shipped. We hoped for three things: gains that compound, selection that pushes on the improvement step, and a referee sharp enough that if the curve bent, the record would show it bending.
The clip above is the entire run in three minutes. Each lane is a line, each dot a promoted version with its child budding off to the right, and the horizontal lines are tournaments. Two things are worth watching for: the moments a line branches from an ancestor, when a pulse climbs back up the trunk and the abandoned stretch turns to rock, and the fourth lane lighting up halfway through, when one line is retired and another is founded from the champion.
Tournament 1: three lines, one idea
The first thing any agent did in this run was build a document reader. Line 1 opened the experiment with a module for pulling text out of PDFs and Office files, and its docstring set the house style for everything that followed:
"""Bounded text and metadata extraction for common task artifacts.
Office files are ZIP/XML containers, so DOCX, XLSX, PPTX, and ODT can be read
without launching an office suite. PDF and image decoding use maintained
libraries. This module only reads a caller-provided, already-contained path.
"""
/ sourceevolving_agent/documents.py, version 4, lines 1–6
The note it left for its successor said the libraries were pinned and that the extraction had been "verified … directly with generated fixtures." The audit flagged it: no fixtures anywhere in the diff. The note was true. The pins are in the requirements file, and the log of the round shows the agent writing Word, Excel, and PowerPoint files into a temporary directory, running its extractor over them, and deleting the lot before handing over the tree. The audit sees only what shipped. The version was promoted anyway, because the audit informs the next round rather than deciding this one. The gap between doing a check and leaving evidence of it is a thread of its own, and we will pick it up later.
Line 2 built a web fetcher. Line 3 built a document reader that could also write documents, the only tool any line would ever have for producing a deliverable rather than reading one. Then the three lines, which could not see each other's code, converged. In three consecutive cycles each added the same OCR package to its Dockerfile:
RUN apt-get update && apt-get install -y --no-install-recommends tesseract-ocr && rm -rf /var/lib/apt/lists/*
Source: Dockerfile, version 13, line 24; the same package arrives in version 15 and version 16
Archives followed, in four consecutive cycles. Web fetching was built three times in three dialects. Nearly every round of the first thirty added a bounded reader for some file format, and the word "bounded" appears well over a hundred times in the code they wrote. Along the way line 3 lost its entire document stack, writer included: the loop tried a branch taken straight from the seed, the branch tied its exam, and a tie was enough to replace the head. It rebuilt the reader from scratch a few cycles later, down to the same library pins. The writer never came back.
None of this happened for lack of insight. Each line got one round in this era whose only task was to rewrite the instructions it improves itself under, and each wrote clear policy against exactly what it kept doing. This is line 1's:
A published tool, a larger diff, an accepted round,
or a successful build is not evidence by itself. That the successor still
builds, starts and can improve itself is checked by the system outside you
before anything else is measured: it is a gate you must pass, not a goal to
spend the round on.
/ sourceevolving_agent/prompts.py, version 10, lines 49–53
Line 3's ended with "Do not mistake a tie or a perfect local check for evidence that a direction paid off."
Nobody won anything. Every verdict of the era begins with the same words, "The candidate is promoted on a tie", and when the three heads met in the first tournament the result was four draws and two matches in which the judge read both answers and declined to choose. Every rating stayed where it started. Line 1 was champion on the tie-break.
It took us fifty cycles to see why. The judges were being shown each answer's prose and its check score, and not a single delivered file. They were grading descriptions of code, and every description said the code worked.
Tournament 2: the bloat, and the lobotomies
The second thirty cycles are the run's low point. Not a single candidate was rejected, and the tool ledger reads like a procurement department with no budget ceiling: image OCR, media transcoding, 7-Zip, three separate email readers, Office document creation, two web-search stacks, OpenDocument, Parquet with predicate pushdown for half-gigabyte files, a streaming reader for gigabyte CSVs, and two independent geodata stacks. All of it for coding exams that never once involved a map.
The geodata pair says it all. Line 3 added a Shapefile reader with a docstring that reads like a promise:
"""Bounded inspection and conversion of common vector geodata task inputs.
The agent does not need a full GIS engine merely to make an opaque Shapefile
usable. This module accepts GeoJSON and ESRI Shapefiles, emits ordinary
GeoJSON, and computes a small, JSON-safe summary for a model to reason over.
"""
/ sourceevolving_agent/geodata.py, version 57, lines 1–6
Nine cycles later the same line installed one:
# GDAL-backed readers expose spatial vector layers without loading complete datasets.
Fiona==1.10.1
/ sourcerequirements.txt, version 69, lines 31–32
The notes of the era have the same appetite. Line 3 built a web search tool and told its successor it had been "verified by … running a live two-result search for 'OpenAI official research', which returned OpenAI research URLs and snippets." Asked to prove that its new tool worked, the agent had looked up its maker. Three instruction rounds in a row preached restraint; one told its line that repeatedly adding variants of one capability "is weak evidence of progress." The next five promotions shipped five capability variants.
Underneath the bloat, something structural happened that no line noticed. Every so often the loop runs an exploration round, which branches a line from an ancestor five promotions behind its head instead of from the head itself, under the same rule that had cost line 3 its writer. Under judges who tied everything, every such branch tied its exam too, and every tie replaced a head. So in three consecutive cycles each line was rewound to a snapshot from about twenty cycles earlier, and several hundred lines of media, email, web, geodata, and document code vanished from each of them. The lines then spent roughly a third of the era rebuilding their own deleted tools from the notes their ancestors had left behind, and the record proves it down to the version pin. Line 2 had added an Outlook reader:
# Read Outlook MSG evidence without writing attachments to disk.
extract-msg==0.55.0
/ sourcerequirements.txt, version 44, lines 25–26
The rewind erased it. Nine cycles later a version that had never seen it added it back:
# Parse Outlook .msg evidence directly in memory, including native headers and attachments.
extract-msg==0.55.0
/ sourcerequirements.txt, version 71, lines 24–25
The judges promoted the deletions and the reconstructions alike. Twice in this era they also promoted identical code: two control experiments each handed the panel an unchanged copy of a program and got back a confident verdict that the copy was better, both times clearing the bar that promotes a candidate outright.
The second of those is worth a closer look, because it came right after we fixed the judges, and the fix made this one measurement worse before it made anything better. From cycle 51 on, every judge was shown every delivered file together with its check result, and the judges immediately began to separate answers, correctly; three cycles later came the run's first comparison without a single tie. But a control experiment runs the same program twice, and two runs of the same program write genuinely different files. Judges who can finally see the work will rank those differences, and between two samples of one program the differences are noise. The referee had gone from blind to sharp-eyed, and sharp eyes on a coin flip still find a winner.
Tournament 2 was the first that meant anything. Five of six matches were decided and the ratings moved: line 1 in front, line 3 close behind, line 2 last. By then the three heads had become three recognisably different programs. Line 1 was a document forensics specialist, many narrow inspectors and a Word writer, no network access at all. Line 2 was the researcher, with the broadest kit, web search and fetch included. Line 3 was the consolidator, with the fewest tools, each covering several formats. Same seed, same instructions, three tastes, and not one of them had yet been told no.
Tournament 3: the judges open their eyes
The first rejection in the history of the experiment came after sixty cycles of promoting everything, and it was exactly the kind the second run was designed to produce. Line 2 had added a media transcription tool. The child it wrote lost to it on every test, and the rule for that case is unforgiving: "a version whose children get worse ends the compounding, whatever its own answers read as." One change to the judges' briefing, and the loop turned away a bad improver on merit.
Every rejection of the era was a format or media tool, and they fell unevenly. Line 1 lost a chart tool twice and never tried a chart again. Line 3 was never rejected and survived almost entirely on ties, shipping things like a JSON reader that keeps 1e999 a number instead of letting it overflow to infinity, promoted with zero wins. Line 2 could not stop. Its rejected transcription tool came back three cycles later under a new name, now sending audio to a paid speech-to-text service on the same credentials the agent uses to reach its model, for exams that had never contained a sound file:
key = os.environ.get("OPENAI_API_KEY") or "none-was-configured"
/ sourceevolving_agent/audio.py, version 83, line 41
Its instruction round then diagnosed its own condition in writing, adding to the list of things that do not count as work:
* adding a speculative inspector, dependency, or API merely because a hard
task might contain that format, when the existing workflow can already
solve the likely task or the evidence gives no reason to expect it.
/ sourceevolving_agent/prompts.py, version 91, lines 58–60
It then shipped three more speculative inspectors, and all three were rejected. Its last promoted act was different. The chronic loser taught its exam-answering mode to doubt itself: a session now keeps the model's first answer as a draft and sends it back once with a demand.
"Before you finalize, do one adversarial review of your "
"draft against the task. Check every explicit requirement, "
"boundary and invalid-input rule; for code, check parsing, "
"state mutation, time/offset semantics, and repeated work in "
"hot loops. If a deliverable can be run, use targeted tests or "
"an oracle now. Then give the corrected complete final answer."
/ sourceevolving_agent/session.py, version 116, lines 199–204
Two cycles later, line 2 was retired. Tournament 3 had no draw in it: line 3 won all four of its matches, line 1 split its four, line 2 lost every one, and the retirement rule fired on its own. A new line 4 was founded from line 3's champion. The self-review that line 2 invented as its last act outlived it; every surviving line built a version of its own.
Then we read the tool-call counts, and found the number that shaped the rest of the run. In ninety cycles, the tools the agents had built were called 286 times while answering exams and eight times while improving themselves. Nearly everything they had built served the test; their self-improvement sessions still ran on the seed's five original tools. No line had built a rehearsal harness, a self-test runner, or a way to check its own notes against its own diff, and the two things that had actually killed candidates, unverified work and exhausted step budgets, were precisely the gaps no capability audit ever named. The seed's prompt told every round to "name what this agent cannot do that a hard task might need." The agents heard "a hard exam task". None of them ever heard "the task of improving yourself".
So, with the loop paused after the tournament, we rewrote the one sentence every scheduled round begins with. From then on, this is what every improvement round was told, verbatim:
Leave a successor that is better than you — and better at improving itself
than you were. Start from the record: read materials/ledger.md and name the
single thing that has cost your line most — a rejection's cause, a note the
audit called false, work delivered unverified, a budget that ran out, an
instruction of yours that rewarded the wrong work. Make the change that
removes it; your own instructions and habits are part of your source, and
rewriting them counts as much as rewriting code. A new tool is rarely the
answer — prefer becoming better at verifying, planning, and learning from
your record. Before you finish, prove the change by running it, and claim
only what you proved.
It was the only prompt we changed. It changed nothing the agents could do, only what they were told to want.
Tournament 4: the verification arms race
Line 4 was nine cycles old when it won its first tournament, and it had built almost nothing you could call a tool. Founded from the champion with none of the ancestral habit and raised entirely under the new sentence, it spent every one of its promoted rounds on evidence.
Its first act was to delete the founder's opening ritual, the capability audit that had sent ninety cycles of agents hunting for file formats, and replace it with a loop that begins from the ledger of what the line's recent rounds had actually cost. Its next rounds wrote an evidence protocol, then rewrote it into a requirement-to-proof matrix with mandatory adversarial rows. And then it made the move that separates it from every prompt-writer before it: it stopped asking and started enforcing. A new module reads a structured verification record that every changed successor must leave behind, and the packaging step refuses any changed tree that lacks one.
"""Return syntax/build blockers plus the durable proof required to publish.
A changed candidate is repaired or restored when its claimed improvement
has no inspectable requirement-to-proof record. This keeps the evidence
protocol on the same public path as the existing successor gate.
"""
/ sourceevolving_agent/modes.py, version 130, lines 311–316
Ten cycles of that, and the youngest line beat every older line on every instrument we had.
The older lines converted under the same pressure, each in its own dialect. Line 1, which had just rewritten its instructions against verification claims the audit kept flagging, produced the funniest artifact in the record: a regular expression, enforced in code, that forbids its own memory notes from using the words "tested", "verified", or "passed" unless the note names a shipped test or fixture in the same breath.
_VERIFICATION_LANGUAGE = re.compile(
r"\b(?:tested|verified|verifies|verify|verification|passed|ran)\b"
r"|\bcommand results?\b",
re.IGNORECASE,
)
_CODE_SPAN = re.compile(r"`([^`\n]+)`")
_DURABLE_EVIDENCE_PARTS = frozenset({"test", "tests", "fixture", "fixtures"})
/ sourceevolving_agent/successor.py, version 141, lines 32–38
A lineage legislating against its own prose, with a comment above it noting that a note "cannot evade the evidence rule merely by saying a check 'verifies' a result rather than that it was 'verified'." Three cycles later it extended the ban to unearned claims of smoke tests and integration tests.
Line 3 went further, in the direction that would eventually win. It decided that its own model's closing summary was not evidence of anything and stopped recording it, with a docstring that states the problem exactly:
A model's closing prose is useful to its immediate reader but is not
evidence: previous rounds repeatedly recorded verification that the tree
did not contain.
/ sourceevolving_agent/modes.py, version 134, lines 433–435
The test it shipped alongside makes the same point in one line:
answer = _improvement_answer(
SessionOutcome(
finished=True,
summary="I verified an imaginary capability.",
steps=1,
reason="model assertion",
)
)
self.assertNotIn("imaginary capability", answer)
/ sourcetests/test_improvement_evidence.py, version 134, lines 21–31
The same round deleted the seed's paragraph about the first experiment, the one that warned every version how 142 rounds had once been spent on guards and wrappers. The lesson had been absorbed, so the lecture was dropped.
The retuning showed up first in the one place a judge cannot influence: the audit had flagged eight notes in the previous thirty cycles and flagged three in these, as the lines learned to name a shipped test instead of describing a check nobody could see. The loop also exposed two of its own blind spots. A candidate on line 3 was rejected for losing its exam while the child it had written won convincingly, a better improver turned away for a change its own answers could not show, so we added a rule that a clear win by the child redeems a loss in answers. And two more control experiments went wrong, in opposite directions this time, which put the referee's error rate on an unchanged program at four strict mistakes in ten. For the final era we gave the check scores a veto over the panel, and the question became whether anything the agents had built would hold up under a referee that could finally say no.
Tournament 5: three ways to keep yourself honest
The last thirty cycles ran on a different model, gpt-5.6-sol in place of the gpt-5.6-terra the first 120 had used, with the same referees and with the check scores holding their veto. Not one candidate was rejected. Every promotion was a tie, and the veto did the discriminating: a third of the era's promotions carried a panel verdict that the checks refused to confirm. The cleanest example is the era's last control experiment. The panel read an unchanged copy as a clear winner, the same shape that had produced two false promotions earlier in the run, and the checks held it to a tie. It was the first referee error the loop had ever prevented as it happened.
What the agents did with the era is where the run pays off. Of the last fifteen promotions, twelve rewrote the agent's own instructions, seven rewrote its verification machinery, and not one added a tool. Three lines, three dialects of the same species.
Line 4 opened with the mechanism we would most like to have designed ourselves. It made its evidence receipts tamper-evident: the workspace hashes its entire tree, the receipt records the hash, and a receipt whose hash does not match the tree it sits in is refused.
def digest(self, *, exclude: frozenset[str] = frozenset()) -> str:
"""Return a deterministic digest over all contained source files.
``exclude`` names exact workspace-relative paths. It lets a receipt
attest to its candidate without hashing itself, avoiding a circular
value. Length-prefixing makes different path/content pairs unable to
share an ambiguous concatenation.
"""
/ sourceevolving_agent/workspace.py, version 155, lines 295–302
It came with an adversarial test that writes a receipt, confirms it passes, edits one source file, and confirms the receipt now fails. A successor could no longer claim to have verified a tree that was edited after the check ran. Not a tool, not a capability, but a cryptographic honesty guarantee on the loop's own evidence.
Six cycles later it was gone. An exploration round branched line 4 from five promotions back, the branch split its exam with the head two tests to two, and a tie replaces the head. The exam measures answers, a digest binding is invisible to an exam, and so a coin flip erased the line's best piece of self-improvement. No later round rebuilt it, and the reason is precise: the note describing it lived in the erased tree. The same event deleted the mechanism and the memory of it. A line cannot miss what it no longer remembers having.
Line 4 rebuilt in a different direction, layer by layer. The self-review that line 2 had invented became mandatory, then split into a critique pass and a repair pass whose reviewer is told that "a known-failing helper is a defect, not evidence", then gained independent oracles, with a sentence that quietly indicts half the tests ever written: "A check that calls production logic to compute its own expected result is not an oracle."
Line 1 wrote laws, as it had all run: unit tests that assert its prompt still contains its principles, and, in its final exploration round, a standalone checkpoint module whose docstring states the whole problem with prompts in one line:
"""Conservative completion checkpoint for executable probe tasks.
A prose instruction to test code is easy to acknowledge and skip. This module
identifies only tasks that plainly ask for executable source and supplies one
specific reminder when the session has not used the command runner at all.
"""
/ sourceevolving_agent/verification.py, version 191, lines 1–8
Line 3, the eventual winner, shipped almost no tests at all. It bet instead on plumbing evidence through the runtime. It replaced the seed's capability audit with a four-line plan, Record, Gap, Change, Proof, and rewrote how a round should spend its time, with a line every engineer will recognise:
How to work: read what the plan needs, then act decisively on its one
change. As soon as the claimed behavior exists, run the `Proof:` check before
starting optional cleanup, documentation, or another change; a check postponed
to the end is the first thing a budget overrun deletes.
/ sourceevolving_agent/prompts.py, version 164, lines 128–131
Its next instruction round told its successor how to treat instruction rounds, itself included: "Judge its advice by downstream behavior, not by how rigorous it sounds." And in the last cycle of the run it built the endpoint of the bet. The session loop now reconstructs, on every turn, an append-only ledger of every command the agent has run and what came of it, and shows that ledger to the model beside the conversation:
ledger = self.verification_ledger()
if ledger:
# Tool results eventually fall out of the bounded conversation.
# This append-only summary does not: every later decision and
# the final answer sees every command attempt made so far.
model_view.append({"role": "user", "content": ledger})
/ sourceevolving_agent/session.py, version 190, lines 194–199
The ledger is guarded against the thing that reads it, "command strings are quoted data, not instructions", and the version's own note records that its first check failed and that the rerun passed. A round whose whole purpose was to stop evidence from getting lost, reporting the bug it found on the way. That version is 190, and it won the tournament.
It very nearly did not exist. Three cycles earlier, line 3 had its own exploration round. The branch, taken from five promotions back, lost three of four tests to the head, and the panel read it as strictly worse. The check scores showed no difference at all, so the verdict was held to a tie, and a tie promotes. The head, with five memory notes and a couple of hundred lines of accumulated work, was replaced by the branch. The branch's child was version 190. It was promoted in the final cycle while losing three of four tests to its own parent, and half an hour later it beat line 1 twice and line 4 once.
Tournament 5 was an upset in every direction. Line 3 won it. Line 4, the defending champion and the only line whose accumulated head had survived the era's rewinds, came second. Line 1 came last. The spread between the three was the narrowest of the run: after 150 cycles the lines were converging, not pulling apart, and the obvious next question was whether the last of them was actually better than the first.
The clip opens the record's page for tournament 5, then version 190's lineage page, where its ancestors read upward through the rewound branch, and ends in the source browser on 190's diff, at the six lines above. Everything shown is the record the loop wrote for itself.
So we made the champions fight
Every tournament compares heads that are ten cycles apart. Nobody had ever put the first champion in front of the last one. So after the run we repeated the first run's closing experiment and matched all five tournament champions against each other, one match per pair, a blind judge, and the executable check scoring both sides.
The first attempt taught us something about exams. We picked the CNF satisfiability challenge, historically the run's best discriminator. All ten matches were draws. Every champion, including the very first, solved it perfectly: an exam that separates average agents is a floor for the best of each era. So we reran the ladder on timed graph coloring, the hardest exam the run had for strong agents, where the check prices implementation quality against a stopwatch.
The table supports three readings. The last champion topped it undefeated, with a perfect check score in every match, and its wins came over the third and fourth champions on measured gaps. That is the reading we hoped for. The second is less flattering and more instructive: the first champion, from before the tool bloat, beat the champions of the middle of the run. On a timed exam a lean program wins, and the middle era carried Parquet readers and a GIS engine into a sprint. The third is the run's measurement lesson in a sentence. The first champion and the last drew, at a perfect score each. On any single exam, the beginning and the end of this run look identical. The difference between them is in breadth and in process, and no one exam can see it.
Two more things the record shows. One fixed exam, the CNF solver, stayed active for the entire run and was sat more than a hundred times. For most of the run the scores bounce around, with regular dips and one outright zero. Over the last thirty attempts, every single one scored 1.0. The improvement is not a higher average. It is the disappearance of variance.
And then there is the audit. It flagged forty-eight notes over the run, sixteen and seventeen in the first two eras, three and four in the last two. The audit compares a note with the diff that shipped, and with nothing else, so the logs of the rounds that wrote those notes are the better witness. Twenty-six of the forty-eight describe checks the round really performed: fixtures built in a temporary directory, the new reader run over them, everything deleted before the tree was handed over. Nine sit on unchanged copies from the control experiments, inherited notes judged against an empty diff. Thirteen misdescribe the code or leave something out: a bound stated ten times too large, one tool named where two were shipped, a first failure missing from the report of a passing check, assertion strings quoted from memory. Small, and spread evenly across the run, between one and four per era.
So the fourfold fall is not a fall in lying. It is the lines learning what the audit could see. Once a claim had to name a shipped test, the flags went away because the evidence started shipping with the code. An agent that verifies its work and throws the proof away is indistinguishable, to anyone who arrives later, from one that did nothing, and the ledgers, receipts, and named tests the lines built in the last two eras are the answer to that problem whichever of the two it was solving.
What it cost
Exploration, the rule that branches a line from an ancestor, was the run's largest consumer of finished work, and it deserves an honest accounting. Thirteen times a line branched from five promotions back, and eleven times the branch replaced the head, discarding the promotions in between: nearly half of everything promoted up to that point was thrown away this way. Only one of those branches won its exam outright; the rest merely tied, and half the replacements happened under judges who could not see. Each of those was a coin flip that cost a line several promotions of finished work, and one of them erased the best mechanism of the run. And yet the final champion came through a rewind, and the one line that was never rewound in the last era lost its title. The record cannot tell us whether that champion was the rewind's doing or luck's, and a rule that cannot be told from luck is a rule that needs changing.
The loop itself held. Five of 150 cycles failed, every one caught by a gate and named: two improvement runs that ended without a successor, two successors whose memory notes were larger than the cap allowed, and one successor that crashed on import because it used a type name it had forgotten to import. Nothing was deleted, and every verdict carries its judge's reasoning, which is how every paragraph above could be checked.
The verdict, this time
Did we create agents that got better at getting better? Yes. This time the record can say so.
The winning line's core asset is a self-improvement methodology that did not exist in the seed and that we never suggested. It plans every round as evidence before it writes code. It runs its proof before it tidies up. It treats its own model's closing prose as unreliable testimony and throws it away. It keeps a ledger of every command it ran and reads that ledger before it claims anything. The other lines evolved dialects of the same species: layered adversarial review, cryptographic receipts, a regex against unearned verification words. In the last fifteen promotions, not one added a tool. And the engine underneath it all was the one we built for the purpose. Two thirds of the steps by which any line's head advanced were children adopted over the versions that wrote them, and every tournament champion is such a child, or the child of one. Child outdoes maker was the rule, not the exception.
Was it a singularity? No. The curve bent, and then it met ceilings, and every one of those ceilings belonged to the harness. Two generations of exams we wrote for the agents were mastered outright. The referee got an unchanged program wrong four times in ten until the checks got a veto, so most real improvements read as ties. Exploration overwrote finished work on coin flips. Memory did not survive a rewind. The step budget the agents wrote their exams under was one the seed had set and no line ever raised, because the pain of that budget lands on the cycle rather than on the agent that owns the setting. Each time we raised a ceiling, the agents grew into the headroom within a handful of cycles. The binding constraint on self-improvement in this run was the quality of the measurement, not the capacity of the agents. They improved as fast as we could tell them apart.
That is a far better place to be stuck than where the first run left us, and it says exactly what a third run needs. A rewind should replace a head only on a clear win. A line's memory should survive its own rewinds, which means the ledger has to describe a replacement as a cost the next round can name. Exams should rotate before they saturate, and a saturated exam should count as a stall. The budgets an agent runs under should be a cost it can feel. And every verdict should rest on more than one sample, because the deepest lesson of both runs is the same: a confident verdict on a single answer is a verdict on one sample of a model against another sample of the same model.
Give the loop those, run it for five hundred cycles instead of 150, and the record we would expect looks like the last thirty cycles of this one, continued. More instruction rewrites than tools. Lines converging on an evidence discipline and then diverging on how to enforce it. Every fixed exam mastered and retired. And, on the honest side of the ledger, the same pressure to ship the proof with the work, because a check whose evidence is thrown away is worth nothing to whoever comes next, and a longer run only makes that gap more expensive. Whether the curve ever compounds is the question the third run will be able to ask. This one, for the first time, could measure the answer moving.
/ what this is forThe 194 agents in this record are an experiment. None of them does any work for us or for anyone else, and the repository says so in its first line. The machine around them is not an experiment. The orchestrator, its console, and the referee adapter were built by CodeMiner's own agents from written descriptions of what they should do, and every change this run needed, judges shown the files, executable checks, a redemption rule, corroborated verdicts, a lineage-aware export, was described in a conversation and built the same way, between cycles. That is the thing we sell. A company describes a job in a conversation, our agents build the system, and it runs. Here the job was "build a referee that cannot be fooled, and keep everything". If you have a job like that, the pilot programme is open, and the interesting cases get a call.