Rebuilt from the spec

I took three programs I had already built, wrote each one down as a specification, and had an agent rebuild it from that text alone, without the original code. Every attempt went into a ledger. These are the ledgers, side by side.

The ledgers: one row per program, one column per run
Programr00r01r02r03r04r05r06ReleasedBuilds
heat-engineWet-bulb, heat flags, weather fallbackoriginal294/336ts362/362ts362/362ts364/364py364/364TypeScript from r03
Python from r04
spec 1.0.2
$1.964 of 6 runs
mcp-tapeA stdio proxy that writes a traceoriginal45/65ts69/69ts69/69ts76/76py76/76py77/77py75/77TypeScript from r03
spec 1.1.0
$3.876 of 6 runs
rcan-assuranceCanonical JSON, hash chains, replayoriginal378/422ts452/452ts466/467ts468/468py468/468TypeScript from r03
Python from r04
spec 1.0.2
$2.124 of 6 runs, r02 unpriced
Blind builds, all three programs$7.94
  • clean: every case, its own tests, a clean audit, and no gap found in the spec
  • passed the suite, but a gap turned up that the spec then fixed
  • failed suite cases
  • cut off before it finished
  • the original program, run through the same suite first

How a rebuild works

The same loop for all three programs.

  1. I read the original program and its sources, then write down what any implementation must do, as numbered requirements, and what it may do however it likes, as numbered open items. Every decision gets a short entry saying why.
  2. I write a suite that judges any implementation from the outside, through a fixed command-line interface, in any language. It runs against the original program first, and every place the original fails is written down as either a bug the spec corrects or a deliberate change.
  3. A fresh agent gets three files: the spec, the decisions, and a one-page prompt. It gets no original code, no web and no other folders, and a shell that runs only its language's tools. Afterwards a script audits everything it did.
  4. I score what it built against the suite and read the choices it wrote down. A run is clean when it passes every case and its own tests, stays within budget, has a clean audit, and none of its choices shows the spec was unclear or wrong.
  5. When a choice shows a gap, I fix the spec, tag a new version, and run again. A language is released only from a clean run, and its code is never edited by hand.

"Blind" means the builder was not shown the original. The model may still have seen these public projects in training. Nothing in the transcripts suggests it, but that is not proof. The isolation is command-line flags plus an audit of every transcript, not an operating-system sandbox.

The layout of each repository follows Carson Farmer's .regenerate/ convention, and the method follows Chad Fowler's writing on regenerative software: a spec, an evaluation that can judge any version, a limit on what the builder sees, and a record of how each version was made.

A heat-stress calculator

regen-heat-engine, released in TypeScript and Python at spec 1.0.2.

Wet-bulb temperature from a 2011 formula, the Marine Corps heat flags and work/rest limits, and a fallback between two public weather services. The original, my HeatCompass engine, already had a spec folder and two implementations held to identical output, which made it the cheapest place to run the whole loop.

Run against the original first, the suite failed 42 of 336 cases, and none of them were in the math. They were units (wind reported in km/h under a field named for meters per second), serialization (one implementation wrote infinity as null, the other as a string), and how the weather fallback fails.

The first two rebuilds passed every case and still did not count. The first found a worked example in the spec that I had typed instead of computed: 25.00 °C where the formula gives 25.05. The second found two sentences about error order that contradicted each other. Each fix was a sentence, and the next two builds, one per language, were clean.

RunLanguageSpecSuiteCleanBuilder timeCost
r01TypeScript1.0.0362/362no3.4 min$0.60
r02TypeScript1.0.1362/362no2.8 min$0.49
r03TypeScript1.0.2364/364yes3.1 min$0.44
r04Python1.0.2364/364yes2.5 min$0.43

A recorder for MCP traffic

regen-mcp-tape, released in TypeScript at spec 1.1.0.

A stdio proxy that sits between a Model Context Protocol client and server, passes every byte through unchanged, and records the JSON-RPC messages to an open JSON Lines trace, with secrets redacted. Its hard parts are streams, framing, end of input, exit codes and platforms, which is where implementations collect knowledge nobody wrote down.

Run against the original first, the suite failed 20 of 65 cases, and two of the problems behind them matter in real use. The original never passed end of input on to the server, and after the server exited it waited for the client, so it hung at the end of every normal session. And two of its redaction patterns took time proportional to the square of a word’s length, so a 2 MB base64 payload stalled it. Later a case turned up one more: it dropped any message member named __proto__.

Once those rules were written down, all three TypeScript builds passed every case, and the third was clean once the spec said what ^ and $ mean in a user’s redaction pattern. Python never came out clean. Its first two programs passed every case on Linux and Windows, but their own tests, written on Linux, failed on Windows, mostly because they expected Linux line endings from a child process. I added that fact as background to a decision, and the next build still missed it; it worked once it was in the requirement itself. The last build’s tests passed everywhere, and its program lost client messages when the server exited first. With all six runs used, only TypeScript is released.

RunLanguageSpecSuiteCleanBuilder timeCost
r01TypeScript1.0.169/69 Windowsno4.5 min$0.57
r02TypeScript1.0.269/69 Windowsno5.7 min$0.70
r03TypeScript1.1.076/76 Linuxyes4.1 min$0.63
r04Python1.1.076/76 Linuxno5.8 min$0.65
r05Python1.1.177/77 Linuxno4.5 min$0.68
r06Python1.1.275/77 Linuxno4.1 min$0.63

A verifier for robot safety evidence

regen-rcan-assurance, released in TypeScript and Python at spec 1.0.2.

It checks the evidence a robot’s safety gate leaves behind under RCAN’s Appendix C: canonical JSON and hashes, the declared envelope of speeds and workspace, a hash-chained log of every gate decision, and a replay of each applied command against the envelope. A verifier is only worth something if someone else can rebuild it and reach the same verdicts.

Run against the original first, the suite failed 44 of 422 cases, and every one told the same story: JavaScript showing through. Infinity was hashed as null, a lone surrogate was written as an escape, an authority of 5 was accepted because 5 is truthy, and a speed limit written as a string was enforced anyway. Four checks the protocol describes were not there at all.

The same suite, run against the canonical JSON writers in my two RCAN SDKs, showed that the three implementations agree on the protocol’s 12 published test vectors and diverge right after them, on number text and key order. Each one claims to match the others.

The rebuilds never needed help with the logic. Chain linkage, the authority audit and the replay rules were right in all four builds. What needed words was serialization and input: how to write a number, how to order keys, which JSON to accept. One build also found a bug in my suite: it treated constructor as an ordinary member name, and my test model did not. The second build was cut off when the cloud machine it ran on restarted; looking into that showed the builder had inherited my session’s environment, which the launcher now clears.

RunLanguageSpecSuiteCleanBuilder timeCost
r01TypeScript1.0.0452/452no4.1 min$0.80
r02TypeScript1.0.1466/467cut off4.6 min–
r03TypeScript1.0.2468/468yes3.1 min$0.68
r04Python1.0.2468/468yes3.3 min$0.63

Across the three

What the three ledgers have in common.

None of the three needed extra words for its core logic. The heat formulas, the evidence chain and the proxy’s rules for end of input and exit came out right in nearly every build once they were written down; the one exception was the last Python proxy, which lost messages at shutdown. What needed more words was the detail at the edges: number text and units in the calculator, key order and number text in the verifier, and in the proxy, regular-expression meanings and the line endings its tests would meet on Windows.

Each original also failed its own spec somewhere that matters: wind speed in the wrong unit under a field named for another, JavaScript’s way of writing infinity in a verifier meant to follow a standard, a proxy that hangs when a session ends. Writing the spec precise enough for a blind rebuild found those before any rebuild ran.

The builds were cheap: 14 blind builds, 5 released implementations, $7.94 for the 13 that reported a cost, a few minutes each. The work around them was not: extracting each spec, building its suite and reading every choice a builder recorded took far longer than the builds.

Check it yourself

Each ledger is a JSON Lines file, one line per run. A blind run's line names the exact spec, decisions, prompt and suite it was given (as git object ids), the model, the audit result, the score and the cost. Transcripts stay out of the repositories; each ledger line carries the transcript's SHA-256 instead.

Any implementation, in any language, can be judged by one of these suites. Give it a folder with a REGEN.json naming its driver, then run node .regenerate/suite/run.mjs --impl <folder> from the repository.