software is becoming reproducible

ยท10 min read
#ai#developer tools#agents

Apr 21, originally. except i didnt publish it then, which is kind of funny because the post already got stale.

the hackathon story was:

jaeyun & i cloned resend and won 2nd place at ralphthon seoul by doing literally nothing for five hours.

the update is:

that wasnt really the interesting part.

the interesting part is that the same loop kept producing product-shaped things after the hackathon. Resend became OpenSend. Mintlify became OpenDocs. Linear became Exponential. and the thing underneath all of it, ralph-to-ralph, stopped feeling like a hackathon script and started feeling like a weird little factory.

still weird.

but less fake.

I

the original story is still true.

at ralphthon, we pointed the system at resend.com, left our laptops at the venue, ate burgers, talked to people, came back, and had a working resend clone deployed to production. real AWS infrastructure. real emails landing in real inboxes. dashboard pages. api keys. domains. webhooks. an SDK.

we showed the judges and won 2nd place.

the part that sounds fake is that neither of us spent the hackathon writing product code. we were working on the loops around the code. prompts. watchdog scripts. phase handoffs. making sure one agent could fail in a way that gave the next attempt enough context to recover.

thats the part people usually miss when they hear "ai cloned a SaaS app."

the hard part wasnt typing React components.

the hard part was designing a system where the agent could notice that the React component was wrong.

II

if you havent heard of ralph, the idea comes from Geoffrey Huntley: put an agent in a loop. when it fails, feed the failure back into context. keep going until it succeeds.

simple enough that it sounds stupid.

and honestly, that is why it works.

ralph is especially good for product cloning because the output already exists. you are not asking an agent to invent a new category or intuit taste from a blank page. you are asking it to reproduce something you can point a browser at. the acceptance criteria are sitting there in public.

buttons should open.

forms should validate.

emails should send.

docs should render.

search should return something useful.

that changes the whole shape of the problem. instead of "make me a product," the job becomes "build me a loop that can see the target, write down what matters, implement slices, test them, and keep its own lies contained."

geoff was one of the judges at ralphthon, which made the whole thing feel extra cursed. hes a friend of mine and i invited him to seoul for the event. so yeah. building an autonomous product cloner in front of the guy who popularized the technique and is known for cloning products with it.

no pressure lol.

III

what we built was three ralph loops chained together.

inspect.

build.

QA.

later, ralph-to-ralph picked up an architecture phase too, which in hindsight is obvious. the inspect loop can tell you what the product does, but it cant always decide what the clone should be made of. you need a separate step that turns "this product has domains, webhooks, billing, docs, auth, search" into boring decisions about data models, infra, auth boundaries, queue workers, and where secrets should live.

boring decisions are underrated. they are usually where the clone stops being a screenshot and starts becoming software.

the first loop depends on Ever CLI.

the problem was simple: how do you clone a product if the ai cant see it?

raw HTML is not enough. products have state. hover effects. forms that only show errors after submit. dropdowns. modals. docs that reveal themselves through navigation. settings pages behind auth. you cant understand a SaaS product from a static dump of markup any more than you can understand a kitchen by staring at one photograph of the stove.

Ever gives the agent a private browser session and a CLI surface. the agent can run a snapshot, get back the page with clickable elements tagged by id, click something, type into a field, scroll, wait, snapshot again, and see what changed.

look.

act.

look again.

that loop is the whole trick. not because browsing is glamorous. because without eyes, the agent is guessing.

at the hackathon, claude opened resend.com through Ever and actually used the site. it navigated pages. clicked buttons. filled forms. read the api docs and SDK reference. took screenshots. after about an hour and a half, it had a spec with 56 features, acceptance criteria, tests, and infra notes. SES for email. Postgres. S3 for attachments. Cloudflare for DNS automation.

then the build loop started.

one feature at a time. tests first. implement. run the suite. commit if it passed.

we watched commits come in from our phones while eating lunch, which is one of those moments where you laugh and then immediately feel kind of unemployed.

IV

the five-hour version was not a perfect production product.

when we came back, inspect had finished and build had gotten through most of the important surface. about 40 of the 56 features were done. email sending worked. domains worked. api keys worked. the dashboard was usable. the remaining queue was mostly settings pages and polish, and the third QA loop hadnt really had time to do its thing yet.

we had about an hour before presentations, so jaeyun and i did the QA ourselves. tested the critical paths. fixed a couple things. prayed a little. normal hackathon behavior, except the thing we were QAing had been written by agents while we were outside.

the repo has moved since then.

the public ralph-to-ralph README now claims the Resend run as 52 features, 24k+ lines of code, 388 passing tests, 10 dashboard pages, 16+ api endpoints, and about 4 hours fully autonomous. the clone sends through AWS SES, verifies domains, configures DNS through Cloudflare, and deployed itself to AWS App Runner.

that clone is now OpenSend, a source-available email infra project you can self-host. not just the hackathon repo with a new badge slapped on top. the README now talks about REST APIs, SDKs in TypeScript/Python/Go/Ruby, React email templates, domain verification, webhooks, broadcasts, automations, contacts, suppressions, inbound email, Stripe billing routes, status pages, OpenAPI, llms.txt, and MCP docs.

which is a very long way of saying:

the demo grew teeth.

V

the bigger update is OpenDocs.

in the old draft i had "namuh-mintlify wip" as a little link at the bottom, almost like an afterthought. now it is a public repo called opendocs, and the remote has hundreds of commits after that original April thread.

OpenDocs is the Mintlify clone, but saying "clone" feels less accurate now.

it has the obvious docs-platform stuff: organizations, projects, MDX authoring, published docs sites, search, navigation, API references, themes, versioning, i18n.

then it has the more agent-shaped stuff: AI assistant/search on Bedrock, llms.txt generation, MCP product surfaces, assistant usage analytics, feedback analytics, GitHub app connection routes, branch previews, deployment records, protected docs, self-hosting docs.

and the infra is real again. Next.js 16, TypeScript, Postgres through Drizzle, Better Auth, AWS ECS Fargate, ECR, RDS, S3, ALB, HTTPS. Sentry and PostHog are wired so a self-hosted default build makes zero outbound telemetry calls unless you configure them.

that last detail sounds boring, but i care about it. a clone that only works by quietly phoning home is not really open in the way developers mean open. it is a demo wearing a repo costume.

OpenDocs is not that.

or at least, we are trying very hard not to make it that.

VI

the Linear clone became Exponential, which is maybe my favorite name of the three. open source Linear alternative, but terminal-shaped. issues, cycles, projects, roadmap, inbox, command palette, self-hosting, Go API, Next.js web, OpenAPI, MCP, Docker Compose, ECS scripts.

there is a pattern here.

OpenSend is not "look, an email dashboard."

OpenDocs is not "look, a docs landing page."

Exponential is not "look, a kanban board."

the clones that survive are the ones where the loop eventually has to touch the annoying parts. auth. billing. SDKs. migrations. worker processes. webhook signatures. API contracts. self-hosting docs. secrets. telemetry defaults. health checks. tests that prove a thing actually does the thing.

that is where the useful lesson is hiding.

agents can make beautiful fake software very quickly. everyone knows that now. the much more interesting question is whether you can trap the agent inside enough real constraints that it has to make software instead of theater.

VII

this changed how i think about coding agents.

i used to think the job was mostly prompt quality. write a better prompt, get a better output. and that is still partly true, but it is not enough.

the real unit is the environment.

the browser the agent can see.

the tests it has to satisfy.

the repo structure it inherits.

the watchdog that restarts it when it crashes.

the phase boundary that prevents inspect from trying to build, or build from trying to QA its own wishful thinking.

the handoff artifact that says: here is what we know, here is what we havent proven, here is what must happen next.

this is why i keep saying the work is moving from writing code to designing the conditions where code gets written correctly. not because humans stop mattering. kind of the opposite. humans matter more at the system boundary.

what do you let the agent see?

what do you force it to prove?

where do you split one giant loop into four smaller loops because the giant loop keeps flattering itself?

when do you stop the run because "it passed" but the product still feels wrong?

those are engineering questions. they just dont look like LeetCode.

VIII

the version of this post i almost published in April ended with "the era of saas is fading.."

i still believe something like that, but less cleanly now.

the era of software as a static artifact is fading, maybe.

the era where a SaaS product can hide behind its UI is fading.

if an agent can inspect your product, write down the behaviors, build a working alternative, and then harden it into something self-hostable, the moat has to move somewhere else. distribution. trust. taste. support. data. compliance. maybe just speed.

i dont know yet.

i do know that "we cloned Resend in 5 hours" is not the whole story anymore.

the story is that the loop kept running after the hackathon.

and the repos are starting to look less like clones and more like a thesis:

software is becoming reproducible.

not free.

not easy.

not automatically good.

but reproducible in a way that should make every SaaS founder a little uncomfortable.

huge credit to jaeyun, who cofounded this whole thing with me. the ralph-to-ralph architecture was very much a joint effort, and a lot of the progress since the hackathon is us repeatedly discovering that the first version was both more powerful and more fragile than we wanted to admit.

if you want to try it yourself, the public repo is namuh-eng/ralph-to-ralph. point it at a SaaS url. expect it to break in some deeply annoying way. then fix the loop, not just the output.

and if youre building anything where agents need to use websites, QA flows, scraping, product cloning, docs inspection, whatever, check out Ever.

without giving agents real eyes on a real browser, youre guessing.

~ ashley