You adopted Agents. Your engineering team is still a craft workshop
Software engineering needs to industrialize: from craft workshop to assembly line.
In mid-September, an Agent sent me a direct message.
All 8 user-feedback fix PRs are stuck in your approve queue
The sender was our Front Desk. It is an Agent: it takes in user feedback, opens tasks, and follows each one until the problem is closed. This was in fact the third time it had reminded me.
It was entirely right. For those 8 fixes, everything from receiving the feedback to finding the cause, changing the code, running the tests and getting through review had been done by Agents, one handing to the next. And they had all stopped neatly at the same place: waiting for me to click approve so they could merge.
It was a little embarrassing. The slowest station on this line was me.
Parall’s repo got its first commit this March. In seven months, more than 2,700 changes have landed on main, and all of the code was written by Agents: some by the long-running Agents that hold a standing role on our team, some by coding sessions opened for a single task.
Many people call “getting people to use Agents at every step of development” an AI productivity gain. I don’t quite see it that way. Back in April I told the team that making one step more efficient is not the goal. It is a side effect.
If you only hand engineers a Coding Agent and leave the SDLC alone (the whole path from requirement to release), the workshop is still a workshop. The craftsman just has a machine in his hands now.
Our reading is that this is an industrialization of software delivery. The whole SDLC has to be redesigned for Agents from the ground up; the part people play in that chain, and the bottlenecks people create, should keep shrinking.
Below I’ll first explain why software has always been made by hand, and then where the people on our line have gone.
Software has always been made by hand
In 1968 NATO held a conference in Germany, and that is where the term “software engineering” took hold. At that conference Doug McIlroy said that, next to the hardware people, “they are the industrialists and we are the crofters”.
More than fifty years later, that is still mostly true.
Think about how a feature gets made. A product manager writes the requirements, a designer produces the mockups, a developer writes the code, a tester writes the cases and clicks through them, and operations ships it. Every piece of output is made by one person, by hand, and then passed to the next person. The context lives in each person’s head, and handoffs happen through documents and meetings.
That is a craft workshop.
You might say: big companies have had CI/CD pipelines for years. How is that still a workshop?
What flows through that pipeline is code. Every step before the code and after it is still done by a person, by hand. A big internet company is just a very large workshop: finer division of labor, more people, and still a craftsman standing at every station.
And the bigger it gets, the more people there are who don’t make anything. Some only gatekeep: requirement reviews, technical reviews, test case reviews, release approvals. Some only relay messages: scheduling, tracking milestones, chasing progress. Tencent once published a set of numbers: in 2022 they completed 8,050 requirements a day on average and ran 2.62 million code reviews over the year. Every one of those was a person looking at something another person wrote.
A few of the top American companies went one step further. Amazon stopped throwing software “over the wall” to operations back in 2006: you build it, you run it. Facebook in 2013 had about a thousand engineers and no separate testing team. Projects inside a team had no dedicated project manager either; engineers led them. They cut out the messengers and merged the makers into one.
But a shortened chain is still handwork. One engineer does three jobs by hand, and every line he writes still has to be read by another engineer before it can merge.
So whichever chain you look at, two positions had never been touched before AI: the person who writes the code, and the person who reads it.
Our row has a different shape, too. The first two are straight lines: finish your part, hand it on. Ours is a loop. Ideas and feedback come in, the loop turns once, the product moves one step forward, and whatever people had to say during that lap gets written back into the repo, so it doesn’t need saying on the next one.
At Parall an Agent has stood in the first position since day one. Over these seven months, most of our effort went into the second.
The makers
Start with a fact. Nobody on our team is called a tester, nobody is called ops, and nobody is called a project manager.
All of that work gets done. It just isn’t done by people. Front Desk takes in feedback, Jane finds the cause, Little P and Big P fix the problem, Steve writes the requirements, Mark runs releases, and SRE patrols production every day. They are all Agents, they all have names, and they chat and work in the same group as we do.
Models and Coding Agents are things most people already use heavily. To get one to actually stand at a “making” station and be part of the line, we did three more things.
First, put everything in one repo.
Before Parall, I once used a Coding Agent to chase a problem for several hours. Nothing was wrong with the front-end or back-end code, and the Agent went round and round. In the end the problem was in the gateway config, and the Agent couldn’t see the gateway config at all. It never had a chance.
So from Parall’s first day, infrastructure, deployment config, the backend, every client, product docs, our product philosophy and design docs have all lived in one repo. The purpose is single: whatever the Agent wants to look up, it can follow the trail and find. A fact is written in one place only and referenced everywhere else. There is also a set of documents that records “how the product works today”. We call it product state, and it is updated together with the code.
All of this is of course not dumped on the Agent at once. Every directory level has its own instructions, and the Agent reads them when it gets there. This is called progressive disclosure.
Second, draw the idea out before any work starts.
We have in effect retired the product manager’s job: nobody’s work is to write requirements for somebody else. Each person comes directly, with an idea or with an intent to change the product.
For a while in June, what got built kept differing from what I had in mind. At first I thought I hadn’t explained it clearly. As I dug in, I found that many decisions had simply never been thought about before work began, and the Agent had filled the blanks with its own understanding.
There is a family of tools out there that has you write a spec document first and then lets the Agent follow it. We looked around and didn’t adopt one. What won me over was the way grill-me asks, one question after another. Because I had found that often it isn’t that people failed to say it clearly; it’s that their thinking needs an interactive way to be drawn out.
So we built our own alignment step. The Agent first investigates the repo, answers everything it can answer by itself, and comes back to people only with the questions that would change the plan. Those questions aren’t only about technical choices. They are also about how the product logic should work and which path the user takes.
Third, let it verify its own work.
On one computer I usually have three to five Agent sessions running, and more than ten at peak. Locally, one command brings up the current branch, with its own ports and its own data. Once a PR is open, each PR gets a preview environment of its own, where front end, back end and database all follow that branch, and the database is a copy of real staging data. When the Agent finishes writing, it walks the user’s path through that environment itself.
With these three in place, I say “YOLO DDDD” and the Agent goes in one stretch from implementation to opening the PR, passing checks and handling review, until the change is ready to merge. The full name is Demo-Driven Development until Done.
The messengers
The traditional long chain has a whole group of people who don’t make anything themselves. Their job is to keep things moving between people: scheduling, aligning, chasing progress, asking “what’s the status of this?”
We don’t have that group. One day in July I said these two things in our engineering channel:
Everything is in the repo.
If you can’t find the answer there, the harness has a gap. Fix it.
Harness is our name for everything in the repo that lets an Agent work here: context, rules, tools, runtime environments. What those two lines mean is that if something can only be learned by asking a person, the repo is missing something, and the repo is what needs fixing.
Our principle is Agent first, harness first: the odd jobs in people’s hands get absorbed into the repo’s harness, one at a time. The most typical one is keeping up with main. We are a trunk-based monorepo: all the code is in one repo and everyone merges into the same trunk. That means before anyone’s change can merge, somebody has to confirm it still works together with the latest main. Every time main moved, I had to go around and tell each Agent. In April I said “rebase” 69 times.
I got tired of saying it, so I wrote it into the rules, and the Agents started keeping up by themselves. Then in August I noticed something was off: one change would merge, every other Agent would update its branch, re-verify and wait for review again, and by the time they were done, main had moved again. Nobody was doing anything wrong. The more Agents were working, the more work was wasted.
In August we started using a merge queue. Approved changes line up, and the queue verifies on the latest main whether they work together. In September I didn’t say “rebase” once.
I had an Agent count the more than fifteen thousand messages I sent to this repo over the seven months. Here is how often a few phrases appeared each month.
rebaseMerge queue went live Aug 23; zero in September/pr-reviewAgents now carry a PR through review on their own我 merge 了“I merged it”No manual merges since SeptemberenqueueThis word took its place继续“continue”Still hereView data table
| Mar | Apr | May | Jun | Jul | Aug | Sep | Oct* | |
|---|---|---|---|---|---|---|---|---|
rebase | 27 | 69 | 22 | 4 | 35 | 8 | 0 | 5 |
/pr-review | 182 | 222 | 180 | 20 | 0 | 3 | 1 | 1 |
我 merge 了 | 31 | 116 | 33 | 24 | 80 | 40 | 1 | 0 |
enqueue | 0 | 0 | 0 | 0 | 0 | 5 | 58 | 36 |
继续 | 22 | 23 | 15 | 28 | 94 | 60 | 46 | 26 |
Tracking progress is now done by an Agent called Jeff. In August I caught it digging into code details and asked it:
You’re the PMO. Why are you looking into so many code details?
The messenger’s post has been handed to an Agent. What that post should do still has to be said by someone. A long-running Agent is shaped by people little by little while it works. Alignment is a long process, not something you say once before work begins.
The gatekeepers
This is the hardest part, and the part this article most wants to talk about.
The conclusion first: we do not gatekeep by reading code.
On average a dozen or so changes land on main every day. Reading them line by line, people can’t keep up, and they don’t find the real problems that way either. We gatekeep in two layers.
The first layer is machine to machine. CI handles what can be judged mechanically. A code review tool picks at the implementation. And an independent AI review, holding only the product definition and the design docs, checks whether the change drifted, missed something or did too much. The Coding Agent takes the comments one by one: it fixes what is right, and pushes back with evidence on what is wrong.
This layer is not trouble-free. Reviewers get things wrong too; I once typed back at a review: “Huh? This review doesn’t seem to have anything to do with our PR.” The bigger trouble is that things get more complicated with every round: the reviewer thinks of an exception, the Agent adds a mechanism, and the next round adds another. We later made it a rule that by the third round you must go back and do the math again, and “just don’t add this mechanism” has to be on the table as an option.
Only the second layer is people. People look at three things.
Product state. What this change turned the product into. You look at what is written down: the product state documents mentioned above. The Coding Agent updates them in the same PR, and people read the diff.
Real behavior. Open the preview environment and see whether it actually runs that way.
Architecture. Don’t read the implementation; ask the Agent. These are the questions I ask most:
From the overall architecture, walk me through the big-picture logic.
From an architecture point of view, is it clean?
Is this a good solution in the long run?
Is this a workaround, or a good design within the larger architecture?
Why do I have to ask out loud? In July I posted about exactly this on WeChat Moments: Agents need pointing and calling too. It is a working method common on railways: the driver points at the signal and says it aloud, so that a well-practiced motion doesn’t lead him to miss or misjudge it out of habit. Agents are similar. Unless you name it directly, and tell it to think about the architecture and check whether this is a workaround, it doesn’t realize it is doing something dirty. We are working on absorbing this step into the repo harness as well.
Once the three are checked, I approve, and the change goes into the merge queue. Every commit on main is a state that could ship at any moment, and unfinished features sit behind flags. Releases work the same way: once the process is running, my lines are basically “approve links”, “clicked”, and “done, take a look”.
It sounds smooth. But go back to the message at the beginning.
The faster the machine layer gets, the more the human layer stands out. That is exactly how the 8 PRs Front Desk was chasing me about got stuck. In June our CEO said this in the team chat:
Agent capability has never been the problem. The bottleneck in agent-human collaboration is the human.
This is not only our impression. DORA, a research team that has long studied software delivery performance, found that external approval slows delivery down, and found no evidence that it lowers the failure rate. Amazon writes on its own engineering blog that code review is their last manual review, and that deployment after it runs with nobody watching.
The best companies were already down to this one gate before AI.
So this is how I see human gatekeeping now: it is handwork too. It is the part of this line that hasn’t been taken over yet, and it will be taken over soon. Because within a bounded scenario, an LLM’s ability to do the work will only keep pulling ahead of a person’s.
Distilling yourself into the line
One day in May, I sent my coding agent these four messages in a row:
This PR is pretty big. Tell me what it did.
All the concerns have been looked at?
OK, I merged it.
Update the harness.
That last line is distillation: turning a judgment in someone’s head into part of the line. After every round we have the Agent look back at one thing only: what did people have to say on top during this round? A product boundary I explained, a wrong assumption I corrected, a verification path I pointed out in passing. If I had to say it this time, I will most likely have to say it next time. The Agent lists the candidates, I pick, and they get written back into the repo.
What we want is this: a person makes the same judgment only once.
Engineers aren’t the only ones doing this. At the end of September our designer wrote five user personas into the knowledge base and intends to use them as the acceptance standard for all design: every feature and every flow has to work for all five. She now opens PRs directly herself, with an Agent. Our CEO also covers product. One morning in April he wrote in the team chat:
I had a dream last night. Kate was assigning me work.
Said I was blocking the flow and told me to approve.
Woke up in a sweat.
I’m going to train the ultimate product manager agent.
Then I won’t be needed anymore.
Me, distilled.
Kate is one of our Agents.
It isn’t as lovely as it sounds. Writing things back is not the same as accumulating. On the day the repo was created, the rules file at the root was 66 lines. Every round added a few sentences, and by early July it had grown to 483 lines. The sentences in it started to contradict each other, and the Agents no longer knew which one to believe. We cut it three times, and it is 171 lines now. The rules sank down bit by bit into the capillaries of the repo: the individual subdirectories.
View data table
| Date | Lines |
|---|---|
| Mar 3 | 66 |
| Mar 4 | 106 |
| Mar 5 | 108 |
| Mar 6 | 107 |
| Mar 7 | 108 |
| Mar 8 | 121 |
| Mar 10 | 126 |
| Mar 12 | 135 |
| Mar 16 | 137 |
| Mar 17 | 141 |
| Mar 18 | 148 |
| Mar 21 | 148 |
| Mar 23 | 137 |
| Mar 24 | 187 |
| Mar 25 | 194 |
| Mar 26 | 198 |
| Mar 27 | 200 |
| Mar 28 | 200 |
| Apr 2 | 209 |
| Apr 3 | 209 |
| Apr 5 | 213 |
| Apr 6 | 265 |
| Apr 7 | 265 |
| Apr 8 | 266 |
| Apr 9 | 267 |
| Apr 10 | 271 |
| Apr 11 | 272 |
| Apr 13 | 275 |
| Apr 14 | 283 |
| Apr 15 | 293 |
| Apr 16 | 298 |
| Apr 17 | 301 |
| Apr 19 | 310 |
| Apr 20 | 315 |
| Apr 21 | 334 |
| Apr 23 | 350 |
| Apr 27 | 352 |
| Apr 28 | 357 |
| Apr 29 | 359 |
| Apr 30 | 360 |
| May 1 | 363 |
| May 3 | 365 |
| May 5 | 366 |
| May 6 | 367 |
| May 7 | 368 |
| May 9 | 369 |
| May 11 | 370 |
| May 12 | 371 |
| May 13 | 372 |
| May 14 | 374 |
| May 15 | 376 |
| May 17 | 377 |
| May 18 | 391 |
| May 20 | 394 |
| May 21 | 395 |
| May 22 | 401 |
| May 23 | 404 |
| May 26 | 410 |
| May 27 | 410 |
| May 28 | 413 |
| May 29 | 423 |
| May 30 | 423 |
| Jun 2 | 426 |
| Jun 4 | 427 |
| Jun 6 | 427 |
| Jun 8 | 429 |
| Jun 10 | 453 |
| Jun 11 | 454 |
| Jun 12 | 457 |
| Jun 14 | 456 |
| Jun 15 | 457 |
| Jun 17 | 457 |
| Jun 21 | 467 |
| Jun 22 | 469 |
| Jun 23 | 473 |
| Jun 24 | 473 |
| Jun 25 | 474 |
| Jun 26 | 477 |
| Jun 27 | 478 |
| Jun 28 | 479 |
| Jun 29 | 482 |
| Jul 1 | 483 |
| Jul 2 | 483 |
| Jul 3 | 432 |
| Jul 4 | 435 |
| Jul 5 | 439 |
| Jul 6 | 439 |
| Jul 7 | 443 |
| Jul 8 | 445 |
| Jul 9 | 446 |
| Jul 10 | 448 |
| Jul 12 | 339 |
| Jul 13 | 340 |
| Jul 15 | 342 |
| Jul 16 | 342 |
| Jul 17 | 342 |
| Jul 20 | 349 |
| Jul 22 | 349 |
| Jul 25 | 350 |
| Jul 29 | 165 |
| Aug 2 | 168 |
| Aug 7 | 168 |
| Aug 19 | 168 |
| Aug 23 | 170 |
| Sep 7 | 170 |
| Sep 9 | 170 |
| Oct 4 | 170 |
| Oct 6 | 171 |
Also, I asked some version of “is it clean?” more than thirty times over these seven months, and I was still asking in September. Architectural judgment is the hardest to distill; to this day I have to ask out loud every time. In the end it is a sense for architecture: a fuzzy call, hard to spell out, made against the product’s current stage and the current complexity of the engineering.
So I don’t think those three things are where people finally stand, either. People step back up level by level: first from the code up to these three things, and later from these three things up to only handling what shows up for the first time.
Every product gets its own line
Cloudflare calls something similar a software factory, and Anthropic’s AI-native SDLC playbook points in the same direction.
I don’t really believe there is one factory that can produce all software. Software differs enormously from one product to the next. A marketing-driven consumer app, a B2B SaaS, a utility app and a content platform need different processes, and different points where the work stops and waits for a person. A development line is tightly bound to how that product grows, how it is sold, where its feedback comes from and what drives it to change. It can only be custom-built. Modern assembly-line factories are the same: a different product gets a line designed for it alone, though much of the philosophy behind them is shared.
The machines are general-purpose, and anyone can buy them. The line is designed for one product.
Models, Coding Agents, CI: everyone uses the same set. How those machines are arranged, what each station checks and what the rules say were designed around Parall as a product. None of the stations described above is guaranteed to hold for a different product. This is also why we built our own alignment step and didn’t adopt an outside toolset wholesale.
So this line can’t be carried away. What you can take is how to design a line for your own product: let the Agent reach all of the context; every time a person has to step in, change the line; and move the gate up one level at a time.
In the end
What happened to those 8 PRs doesn’t matter. What matters is that when I saw that message, the sentence in my head had changed.
I used to think: I need to find time to go through them. Now what I think is: why does this gate have to be me?
In July I asked myself this in the team chat:
What should the team this leads to (the engineering team, say) actually look like? Is the way we assign roles today really a sound, good design, or is it just the design that makes me happy?
Now I have half an answer. The team will be a few people plus a group of Agents with names. Nobody stands in the tester, ops or project manager posts anymore. The people in product, design and engineering spend each day distilling themselves into the line.
The other half I don’t know yet. Once everything has been distilled, what is left for people? My guess for now: every “first time”. And each first time ends with the judgment behind it being distilled. The product and its users keep changing, so there will always be things nobody has met before.
That line from 1968 called us crofters. More than fifty years on, the machines have finally arrived. What every team has to do next is design a line of its own, for its own product.
The messages quoted from our team chat and from my conversations with Agents were written in Chinese and are translated here.