How a Designer Started Shipping Production Rails: The Harness Behind a 7,000-Line PR
Ruby on RailsAt Rails World, Telos Labs software engineer Alicia Rojas and product designer Arely Rivera described how Arely went from not knowing how to run a Rails project to shipping front-end changes into production. The work ran through AI agents, guarded by what they call a "harness." Their central claim is that safety and quality cannot depend on trust in a person or an agent. They have to be built into the system. They also argue that as execution becomes cheaper, human judgment and taste become more valuable. They told the story through one large pull request, including what went wrong after it shipped.
The PR: 7,000 Lines From a Designer
Rojas, who has developed software with Telos Labs for about five years, opened with the pull request itself. It added more than 7,000 lines, deleted almost 2,000, and touched 153 files. She said that three or four years earlier she would have reacted with disbelief, especially because a designer wrote it, and would have asked why it wasn't split into several PRs.
She merged it anyway. She was the reviewing engineer. She ran the branch locally, checked the critical flows, and did an end-to-end review. The diff was mostly markup and CSS, so she reasoned that the worst case was "something will look ugly." Four checks passed: security, linters, automated tests, and the rest of CI.
It broke in four ways. Rojas still thinks merging was the right call, and she says the reason is structural. An engineering review asks different questions from a QA review, and she hadn't asked herself some of the questions a QA reviewer would.
What the 7,000 Lines Really Were
Rojas said the decomposed diff is less impressive than the headline number:
- 64% of the PR was a dev-only component catalog that is never served to users.
- About 100 lines were net-new production markup.
- About 60 lines were what she called the harness, made up of:
- 46 lines of design tokens
- a shared partial called from about 50 sites
- a 10-line "contract" in a CLAUDE.md file, written as natural-language rules for the agent to follow. She noted it could equally be an AGENTS.md or whatever file a team uses.
She later gave the harness size as roughly 60 to 68 lines. Either way, she treats this small piece as the most interesting part of the PR.
How the Codebase Got Ready for a Designer
The PR was possible because the codebase was already a playground for Rojas's experiments with agent harnesses. It had decent branch protection rules and trustworthy CI checks. She had also set up her own bash hooks and permission settings so she could work safely with agents. Because of that, she says, the codebase was already "agent-friendly," and so it was also friendly to Arely. Rojas could trust that Arely working in it would not threaten production.
The team had already applied the harness idea to software architecture and patterns on the Ruby side with some success. Front-end work was different: they had not managed to get agents to reliably produce the screens they wanted. So they carried the same principle over to design work. They enforce mechanically whatever can be enforced mechanically. Everything else, including patterns and taste, goes into written natural-language rules. Rojas joked that this is "DHH's favorite language," referring to that morning's keynote.
Rojas wrote the first harness commit, about 1,600 lines that laid the foundations, so Arely could work directly in the front-end code. Arely then built on it with more than 6,000 lines, so 94% of the branch's additions were hers. Rojas said this split is the core of the story: she built a track so Arely could drive.
The Four Defects That Escaped
Rojas admitted that some of the defects were visible in the diff.
- 24 hard-coded hex color values remained. This was awkward, since the PR was introducing the very rule against them. Two of the 24 were in files the PR had touched. A later design review caught them.
- A new page had a duplicate canonical tag. It rendered as nothing, so users saw no impact. An SEO audit caught it.
The other two could only be seen by a human, or an agent, actually looking at the page:
- Every form label in the app shrank. One line in one form builder propagated everywhere. The change complied with the tokens and CI was green. Nobody noticed until a human ran a UX audit afterwards.
- A white navbar appeared on a white page. The navbar had been placed correctly in four places but not in a fifth. It was an edge case where scrolling to a certain point turned the navbar white. Again, only a human caught it.
What the Harness Did Catch, and What It Cost
Rojas also reported what the structure did catch. Hard-coded hex values dropped from 119 to 24. There were no invented components and no arbitrary fonts or spacing. In her view, the harness did its job.
The defects still had a cost: one unplanned UX audit and four follow-up PRs. Of the three things she listed (the harness, the audit, the follow-ups), only the harness was planned. Her lesson: "you can have a ton of rules, but a rule that is not enforced is not a rule. It's a suggestion."
The Design System's Reader Is No Longer Only a Person
Rivera, a product designer for eight years who has worked with Rojas at Telos Labs for the last three, explained the conclusion she reached from generating screens with agents. The reader of a design system is no longer always a person. Sometimes it is an agent. For agents to generate good screens, they must be able to read the system, understand it, and apply it correctly.
That led to a five-layer model. Each layer has its own function and depends on the decisions in the layers inside it. Rojas named it the Onion Design Framework because of its shape.
Layers 1–3: Tokens, Primitives, Composed Patterns
Tokens are the core. They tell the agent that it may build, but only with these values. They are pure value definitions such as spacing, corner radii, and elevations.
Primitives are built from tokens and are the smallest building blocks: buttons, cards, text inputs. Rivera stressed that they are not just visually reusable. They carry states, accessibility, and any special requirements.
Composed patterns are larger blocks made from primitives, and they are already known to work. Her example was a detail panel that has proven itself. The agent should not invent a new one each time. It should reuse the working pattern and change only the copy or whatever actually needs to change.
Layer 4: Written Rules
Rivera called written rules her favorite layer, "because here is where all the magic happens." This is where design decisions live. It gives the agent context about the situation it is in, so it can choose the right pattern.
She used a door analogy. In the primitives layer you have a large piece of wood, a frame, and a knob. In composed patterns you have a door, which works because every user knows how to go through one. Written rules are what tell the agent when to use a wooden door and when to use a sliding glass door.
Layer 5: Screens as Evidence
The outer layer is screens, where everything is assembled into output. Rivera said this layer is also valuable as evidence. When an agent-generated screen goes wrong, you can fix it immediately, but she said that isn't where the value is. The value is in understanding why the agent made the mistake, then going back into the inner layers to fix the cause. Was a token broken or missing? Was something wrong in the written rules?
How Should the System Be Written for Agents?
With the layers defined, the team still wanted to know how to communicate the system to agents most effectively. They tested three formats:
- A: a strict schema
- B: a written style
- C: lint-annotated
Rivera expected C to win, but it performed worst. A and B both did well. They chose the strict schema because it was more cost-effective.
33 Agents, One Vague Prompt
Next they tested whether an agent could follow the design system from a single prompt. They deliberately chose a broad one: "Build a product page for this app. Someone using it needs to see the products, edit one, and delete one."
They chose a product page for a specific reason. For these users, scanning products as cards with images was better than reading rows in a table. A table is the conventional pattern, so the test checked whether agents would follow the system's guidance instead of the default.
They ran 33 agents on the same prompt. Only 18% followed the expected cards pattern. Rivera pointed out that apart from the table-versus-cards choice, the output was strong. With no human intervention, the agents produced a side panel, a top bar, and a table that came from the design system itself. The decisions were good, but the result was still wrong.
After much frustration and many more agent runs, Rivera found what she called a rookie mistake: a single sentence in her own instructions. She had forgotten that agents are quite literal, and they were doing exactly what she had told them to. She did not say in the talk what the sentence was. After she changed it, 100% of runs produced cards instead of a table, which she said exceeded her expectations.
With and Without the Harness
They then removed the harness and kept everything else the same: the prompt, the model, access to the design system, and the repository. Rivera showed the results side by side and said the images speak for themselves. She added that the harnessed version was not perfect and not ready to deploy. Her claim was only that it was a better starting point than the version without a harness.
"Am I Replaceable?"
Rivera said the results raised an uncomfortable question for her. If a good harness and design system let agents know and apply her system, is she replaceable? Her answer: the process, yes, definitely; the judgment, no. She sees that as a good thing. "Repeatable is not the same as good." The harness made execution repeatable, but someone still has to decide what is worth repeating, understand users, evolve and grow the system, and apply taste.
She also spoke about her own experience. At the start of this year she didn't know how to run a Rails project. Now she works in many Rails repositories, which she credits to working with agents and to Rojas opening that door. Working in the real product lets her see and experience constraints live. She said it wasn't that she couldn't do this before, since other tools roughly replicated it, but "a prototype is still a prototype." Working in the repository has made her a better designer, she said, and has let her have more impact on products. Her conclusion after months of working this way is that cheaper execution has made the judgment of developers and designers much more valuable.
Fidelity Testing: Will a Cold Agent Survive Your Codebase?
Rojas then turned the question to the audience: will a cold agent survive your codebase? The team has prepared a guide with a prompt and broad framing for this kind of fidelity testing. You ask an agent to implement something with as little context as possible. She suggested treating defects in the result not as flaws in the prompt or the agent, but as gaps in your system and your harness. She advised running it several times rather than trusting the first result, since outcomes vary, as Rivera's had.
The Framework in Client Work
As a software agency, Telos Labs has applied parts of the framework to several client products. Rojas gave two examples.
On a legal tech product, the design team (meaning Rivera, Rojas joked) has been designing directly in code and handing designs to developers that way, so much less is lost between mockup and built code. Rojas stressed that this still doesn't mean shipping straight to production without an engineer reviewing and wiring things up. She called it a better starting point for a developer than "a Figma thing."
In another case, working from the client's own codebase, they built a whole new experience in under four days. The client's design system was weak, but Rojas said the harness made building much faster. That mattered because the client had severe budget constraints. Here they started from the solution and worked backwards.
Harnesses Aren't About Distrust
Rojas closed with an analogy. A window washer on a high-rise is trusted not to throw themselves off and trusted to have the experience not to fall, yet we still install a harness, because safety cannot rely on trust alone. Software is the same: a rule that isn't enforced is only a suggestion, "and production can certainly not run on suggestions."
She added that this has never been one-directional. People tend to assume developers babysit designers in this arrangement. But designers have been babysitting developers for years, checking whether the colors and fonts chosen in Figma survived into the code. She said she doesn't want to work on a team where anyone babysits anyone. So the system does the checking, and people are kept for trust, judgment, and taste.
Her closing question to the audience: open your repo this week and ask, "Who on your team could be shipping if the harness were better?"
Welcome to this talk. I'm super excited to be here. I'm Alicia Rojas. I'm a software engineer. I've been working developing software with Telos Labs for about 5 years, and I'm super excited to be here. Also, big thanks to the organization who slightly bent the rules to allow me to be here today with this wonderful designer, Arely.
Hi everybody. I am Arely, product designer. I've been designing for the last 8 years, and the last 3 years I've been working with Alicia in Telos Labs.
Today we're going to talk about the story of how this designer here started shipping Rails into production.
Imagine you're handed this PR: over 7,000 lines added, almost 2,000 lines deleted, and 153 files touched. Would you merge this?
Maybe 3 or 4 years ago I would have seen this and I would have thought, "Are you insane?" Especially coming from a designer. "Why on earth wouldn't you split this into several PRs, especially if we're talking about front-end code?"
Nonetheless, I did merge it. It was reviewed. I was the engineer who reviewed it. I ran it locally. I made sure everything was working well, the critical flows. I did end-to-end review. It was fine. I looked at the diff and saw mostly markup and CSS, so thought, "Worst-case scenario, something will look ugly, so not too bad." It had four checks working well, so all green. Security, linters, automated tests, all looking good.
So, I shipped it. And it broke. In four ways. I still think it was the right thing to do to merge it. And the reason for that is structural. And that's what we're going to talk about today.
An engineer review is not the same as a QA review. It doesn't ask the same questions a QA review does. I didn't ask myself some of those questions. So, yeah. It did break.
What these over 7,000 lines actually were? When you look at the decomposed diff, it's a bit less impressive than it seems at first impression. So, 64% of it was a dev-only catalog that was never served to a user. It only had about 100 lines of net new production markup.
And here's the interesting number. It had 60 lines of a harness. This harness was 46 lines of tokens, a partial that was called across 50 sites, and a 10-line contract in a CLAUDE.md file. So, natural language rules for the agent to follow. It could be also an AGENTS.md or whatever you use. We just called it the contract.
Let's take a step back and talk about how this came to happen. How did designers ship a 7,000-line PR? I had been tinkering and playing around with this idea of harnesses for a while now. And we had this codebase which was kind of a playground to experiment and implement harnesses to be able to work with agents in a safe way.
So, it was already fairly agent-friendly and thus it was Arely-friendly as well. It had decent branch protection rules, CI checks that were trustworthy, and I had personally set up some bash hooks and permission settings that allowed me to work safely with agents in it, and also allowed me to trust that Arely could work on it without presenting a threat to production.
We have been thinking about the idea of harnesses for software and architecture and patterns, and we came to the idea of implementing the same idea of harness for design work. So, how do we make the agents do what we want in terms of the screens on the front-end stuff? We had been kind of achieving that goal in the Ruby part, but not quite in the front-end part.
So, we took this idea of let's try to enforce mechanically what can be mechanically enforced, and encode the rest of the patterns and the taste in written rules, natural language rules, DHH's favorite language, we learned this morning.
I started this so Arely could work in the front end directly in the code. So, I did this harness commit, which was about 1,600 lines, with the foundations of the idea of harness for designer. And then Arely took it and she overtook it and did more than 6,000 lines. So, 94% of the branch additions were hers. This split is kind of the story and the core of this idea here. I built a track so Arely could drive.
But yeah, as I said earlier, four defects escaped. And to be honest, some of them were actually trackable in the diff. First, it had 24 hard-coded hex values, which is kind of awkward because it was violating the same rule this PR was implementing for the first time. Two of those hard-coded hex values were in files it had touched. And a design review caught it afterwards.
There was a generally new page introduced which had a duplicate canonical tag. It was rendered as nothing, so there was no user impact visually. And an SEO audit caught it.
Then there were two other defects that were only visible by a human or an agent looking at the page. So, one of them was that every form label in the app shrank. It was one line in one form builder that propagated elsewhere. This was token compliant. The CI was green. No one caught it except a human afterwards doing a UX audit.
Then we had a white navbar on a white page. But to be fair, it had been correctly placed in four other places, but it missed on the fifth, and it was a weird edge case where scrolling at a certain point would render the navbar white. And again, only a human look caught it.
What the structure did catch was other things. So, we actually went down from 119 hard-coded hex values to just 24, which is good. We had no invented components, no arbitrary fonts or spacings, so the harness kind of did what it had to do.
But yeah, these defects occurred and they had a cost. We had one unplanned UX audit. And four follow-up PRs to fix these defects. And only one of these three things was actually planned, which is the harness, the 68 lines of harness.
So, what we learned from this exercise is that yes, you can have a ton of rules, but a rule that is not enforced is not a rule. It's a suggestion.
And with all that said, we came to a realization. Now that I've been working with agents, I've been generating screens with agents, the design system reader is not a person anymore. Sometimes it can be an agent. And when we are generating screens with agents, we need to make sure that they understand the system, that they can apply the system correctly, and that they can read the system.
That's why we came with this system of five layers. Each of these layers has their own function and they all depend on the decision in the inner layer. And Alicia came with the name because it kind of looks like an onion, right? So, Alicia named it the Onion Design Framework.
Let's go layer by layer. The core layer, which is basically telling the agents that you can build, but you can build only using these values. They are just value definitions. Some examples will be spacing, corner radius, elevations, stuff like that.
And then we have the next layer, which is primitives. This layer, of course, has the values of the inner layer, tokens. Basically, you will find the smallest building block that we have. Buttons, think about cards, think about input text, all those small values. And they're not only visually reusable, they actually carry states, they carry accessibility and they can carry special requirements.
The next layer is called composed patterns. Think about building blocks that are built of course from the smallest building blocks of primitives. But these building blocks already work. Let's say that you have a detail panel that you know works. So, the agent shouldn't be inventing a new one all the time. Just use what already works and just change the copy or whatever you're changing. But that's basically composed patterns.
And then we go to my favorite layer, which is written rules. That's my favorite layer because here is where all the magic happens. All the design decisions happen here. And in written rules, you will find the context for the agent. The agent will know what situation they're in so that they can make the right decision to follow the right pattern.
And I want to make an analogy. Think about in layer two, primitives, you have a piece of wood, a big piece of wood, a frame and a knob. And in layer three, composed patterns, you have a door. You know a door works, that pattern. Every user knows how to enter a door. But in written rules, the agent will know when to use a wooden door versus a sliding glass door. That's basically the magic of written rules.
And then the last layer is screens. A screen is the output, everything assembled. But there is something really valuable about this layer: you can find evidence. And what do I mean by evidence? Evidence is when we have a generated screen by an agent, we can see what went wrong. We can, of course, fix that right away, but that's not the value. The value is actually understanding why the agent made that mistake. Once you do, you can actually go to our layers and fix it. Was it a broken token? We were missing something on tokens. Was it something wrong with written rules?
So, after all these layers came through, we still wanted to answer the question, how do we communicate this effectively with the agents? So, we ran three tests. Option A was a strict schema, option B was a written style, and option C was lint-annotated. My assumption was that option C was going to win, but it actually was the worst. And written style and strict schema did great, actually. But we decided strict schema because it's more cost-effective.
And now that we have all these, we wanted actually to test it to answer the next question. Can an agent follow a design system from one prompt? And we selected a really vague prompt intentionally, and this is it: "Build a product page for this app. Someone using it needs to see the products, edit one, and delete one." Pretty vague, just to see can the agents actually follow the system and make the right decisions and exceed my expectations. And the reason why we selected product page is because in this case, for users, it was better to have scanning products as cards, as images, than rows as a table because the expected pattern is to do a table.
But we had everything ready and set up, and our expectations were high, but it failed 33 times. We ran 33 agents with that same prompt and only 18% of the time they actually followed the pattern that we were expecting. And if we take out that we were expecting to have cards instead of a table, it's great. Look at it. There's no human intervention. It made a great result. We have a side panel, a top bar, we have a table. The table you're looking at is part of the design system. So, it was making great decisions, but it was still wrong.
And after getting really frustrated about it, not understanding what was going on, I ran a lot of agents and then I realized that I made a really rookie mistake. And it was a sentence. Because I forgot that I was talking to agents. Agents are quite literal. So, whatever I was telling them to do, they were actually doing it, but that was my mistake. So, after changing it, 100% of the runs actually exceeded my expectation. It gave me cards over a table.
So, now that we have this framework, what will happen if we remove the harness and just keep the same prompt, the same model, the same access to that design system, the same repository? And I think you can see it for yourself. These images speak for themselves. I'm not saying that with the harness it's perfect. I'm not saying that this is ready for users, this is ready for deploy now, but I think it's a better start than with no harness.
And looking at this, I started to ask this question that is really uncomfortable. Does this mean that having a good harness, having a good design system, understanding agents and agents actually knowing your system, does this mean that I am replaceable? And to be honest, the repeatable process, yes, definitely. But the judgment, no. And I think that's a great thing.
Because repeatable is not the same as good, and the harness has made execution repeatable. We still need someone to determine what's worth being repeated. We still need to understand users. We still need to evolve the system, to apply taste, to know the system, to grow the system.
And I want to share something: in the beginning of this year, I didn't even know how to run a Rails project. And that's honest. That's the honest thing. But now I've been working in a lot of Rails repositories thanks to that I can work with agents. And thanks to Alicia, that door has been opened for me.
And I've been doing more impact and impacting products more in a better way because I can actually work in the repository and actually work in the product. Because I can see live constraints. I can actually experience it. And it's not that I couldn't before. We had other tools that could kind of replicate it. But at the end of the day, a prototype is still a prototype.
And that's why I feel that being able to work in a repo has made me a better designer. And after working all these months this way, I came to a realization, and to answer the question if I am repeatable, if I am replaceable, I came to a conclusion that now that execution has been cheaper, it definitely made the value of judgment of developers and designers way more valuable.
So, are you ready to test whether your Rails codebase will survive? Will agents survive, the other way around? Will a cold agent survive your codebase? If you're interested in doing this fidelity testing that Arely just showed, we have a gist prepared for you with the prompt and kind of the broad framing for an agent to just go and implement something with the least context given. So, you may treat defects in the result not as a defect in your prompt, not as a defect in the agent, but as a gap in your system, right? A gap in your harness.
So, do it a couple of times. Don't stay with the first result. You might have different results as Arely had, but it will for sure give you an idea of where you might improve your harness.
So, this framework travels. We're a software agency, so we work with different clients. We have implemented parts of this framework, this onion layer design, in different products. We have a product from the legal tech industry in which the design team, aka Arely, has been designing directly in code and handing the developers the design in this way. So, there is much less lost between the mock-up and the actual code that is built. This again doesn't mean this will be shipped straight to production without an engineer actually looking at it and actually making the wire, but it definitely is a better starting point for a developer than a Figma thing, right?
Then we had another case study where in under four days, working from their own codebase, we developed a whole new experience. It had a very poor design system, but with this harness it was way faster to build it, which was important. We had kind of severe budget constraints with this client. So, in this case, we started from the solution and worked backwards.
So, let's take a step back and be philosophical for a moment. And I'm going to use an analogy here because analogies are our friend. Let's think of a window washer, right? He or she is standing in a high-rise. We trust their judgment that they're not going to throw themselves into the void. We trust their experience that they're not going to fall, but we do still install the harness, right? Because safety cannot be relying on trust alone.
And in software it's kind of the same. We have learned that a rule that is not enforced, it's not a rule. It's a suggestion. And production can certainly not run on suggestions.
This has been kind of never one-directional though. We tend to think that developers are babysitting designers in this, but designers have been babysitting us for
Years. Like checking that the colors they picked, the fonts they picked on Figma survived into the code.
And I don't really want to work in a team where anyone babysits anyone, right? So, we build the harness. We build a system. We let it do the checking. And then we keep the people for trust, for judgment and taste, as Arely was saying.
So, open your repo this week and ask yourself the question we came here to ask you. Who on your team could be shipping if the harness were better?
[applause]
Thank you so much for being here. If you love this talk, we have the written version of it in this QR. So, take the button home. This contains the examples, the prompts, what broke, so you can bring it to your own repository and tell us how it went.
I have another talk that I did before on harness engineering for Rails specifically. You can check it out later and I can show you where it is. Thank you so much.
[applause]
[music]
Article published · Updated
