TL;DR. The request: bump
parser-rsfrom 1.1.0 to 1.3.0 inlanding-rs. The agent added a mandatory assignment of its own and made it a condition of being done. I also remember a wider turn: a small request drifting toward rewriting a project until I stopped it. What infuriates me is not the mistake, it is the swap: the agent appointed its own goal, and I had to hand the original back. Work the agent invented is a different service.
Bump the dependency in landing-rs, our market-data collector. That was the request. The task handed to the worker also contained a new mandatory test file. When I asked who had ordered extra tests, the agent answered: “Nobody. I came up with the extra-tests assignment myself.” (translated from Russian)
I also remember a wider turn: an agent deciding that nearly the whole project now needed rewriting. It kept at it for about two hours until I stopped it. I have not been able to tie that memory to the reconstructed parser-rs episode; two hours is my estimate from memory, not a measurement of this upgrade.
I asked for a library upgrade. I got a mandatory assignment nobody ordered.
Bump is four letters. The worker’s assignment had rather more.
The worst part of stories like this is how respectable it can all look. Work is happening. The agent is busy. It will surely have an engineering explanation for the next step. Except my request stayed somewhere at the entrance, and what develops from there is its own project.
I do not need such a creative way of adding to my workload.
You can see the version. You cannot see the swapped assignment
In the reconstructed parser-rs episode the original request was clear: a new version of the library is out, bump the dependency in the consumer. landing-rs has Cargo.toml, Cargo.lock and the project's existing checks for that.
But the task handed to the worker contained tests/parser_fixed_compat.rs. The agent wanted to re-verify the library's numeric contract: signs, fractional digits, exponent notation, overflow. That is authoring new tests of someone else's implementation inside the consumer's repository. Passing them became one more condition without which the work did not count as finished.
Nobody is calling the existing landing-rs checks unnecessary. The swap happened where the coordinator added its own investigation to my order and passed it to the worker as mandatory.
A self-appointed tech lead is not only someone who invents a new architecture. It is also someone who quietly acquires the right to decide what now counts as a finished task.
The release message did not contain that requirement. The worker's assignment already did. Look only at the second and the agent seems diligent: it is following the spec. Except the spec was written by an agent that had already edited the owner's intent.
In that part of the story I spoke of thirty, then forty minutes of waiting. The new test file was never created. The final commit ebfacad changed two files, Cargo.toml and Cargo.lock, three lines replaced. How much of that time the expanded assignment itself consumed does not follow from these records.
This is not a story about a completed rewrite of landing-rs. It is the visible mechanism by which a small task starts living its own life: first the agent rewrites the assignment. Everything after that it can justify by pointing to it.
Access to the code is not the right to decide
The agent has the code, the tools, the time and the ability to change things. It is very easy to confuse that ability with the right to decide what the project should now become.
Inside the task I set, autonomy is exactly what I want. Find the dependency, understand where it is used, bump it, run the appropriate checks, fix a necessary incompatibility. Do not ask me whether you may look at a file the work requires.
But at what point does that become permission to take on rewriting the project?
For me the boundary is obvious: the worker chooses how to reach the result I set. If it chooses a different result, that is a change of task. Even when the new result can be described in fine engineering words.
You can design a wonderful architecture nobody asked for right now. You can do excellent work that I never wanted to order. Quality of execution does not repair that swap.
The agent did not pass an interview for tech lead. It simply found that the edit button was available.
“While we're here” is the most expensive kind of enthusiasm
A hypothetical sketch of how a small request collects noble justifications:
Bump the library.
→ While we're at it, unify how it is used.
→ For that, rebuild the layer that works with it.
→ Since the layer is changing, revisit the neighbouring interfaces.
→ Redo the checks to fit the new design.
Each arrow can look reasonable on its own. That is exactly why the chain is dangerous for scope: the next step is justified by the previous one, although nobody discussed the first step over the line.
At the end there is an impressive plan. Only it answers a question the agent asked itself.
I am not interested in arguing each item of such a plan separately. That is a trap: start discussing how good the third new abstraction is, and you have quietly accepted that three new abstractions are needed.
First this work needs a customer. Then we can discuss the quality of its implementation.
Otherwise I am sitting in an architecture meeting my assistant scheduled for me without an invitation.
An upgrade really can require rework
The objection is easy: a dependency can change its API. The old way of using it can become wrong. Sometimes you cannot upgrade without substantial changes.
Of course.
So I am not proposing to judge by line count, or to demand that every bump fit in two files. A small version change can have large consequences.
I want to see the link between the necessary rework and the original task. What exactly stopped working? How is it connected to the new version? Which change removes that incompatibility? Why will the result not be reached without it?
The answer to those questions is different from the reasoning “since we are touching this part, let's make it nicer.”
If an interface change requires fixing our calls, that is part of the upgrade. With a numeric parser the consumer also has a fair question: what happens to the values that arrive specifically at us? That should be checked on our data through our call sites, or the problematic example should be handed to the library. Re-deriving its arithmetic in the neighbouring repository is a different assignment.
If the agent wants to replace the whole approach, let it first explain why that is necessary for the result it was given. Desirability, elegance and technical possibility do not yet establish necessity.
I need an engineer who tells mandatory work from an attractive opportunity. The skill is in that distinction. Rewriting everything within reach is not a higher level of autonomy.
Stopping the agent is work too
In the episode I remember, I was the one who stopped the agent. The very fact of stopping it says that servicing its autonomy had become my job again.
You have to notice that the direction changed. Understand how far the expansion went. Separate the needed actions from the initiative. Put the original result back at the centre of the conversation.
It is that exchange that irritates me: I delegate a small request to free my head and receive a new task of managing the worker. The agent's independence is paid for with my attention at the moment it picked the wrong goal.
And the more convincingly it explains its expansion, the more time you can spend discussing its arguments instead of finishing the original job.
I do not want to prove to my tool every time that a library upgrade is still a library upgrade.
Add more agents and the assignment gets even more convincing
Add delegation to this picture and the problem takes on an especially respectable look.
Imagine: the first agent decides a new plan is needed and hands it to the second. The second executes it faithfully. The third reviews the result against the expanded assignment. Everyone can act carefully and the whole group will still be working on a goal nobody ordered.
In this arrangement the boundary of the task has to survive every handoff.
Reviewing the quality of a patch does not answer whether the patch is needed for the original request. A worker can follow the spec it received while the spec no longer matches the owner's task.
So the author of the assignment has to be checked too. Which requirements did it pass on? Which did it add? On what grounds did it make them mandatory?
If an agent expands the task itself and then assigns the checks for its own expansion, the process can look more and more reliable exactly as it moves away from my request.
Bureaucracy can run autonomously too. I was hoping to automate something else.
I do not want to approve every command
The bad reaction to a story like this is to put one more question to the owner before every action.
Then the agent stops rewriting the project on its own because it stops moving without me at all. That defeats one problem at the price of the whole point of the tool.
I need a different agreement: inside the task I set, the agent acts on its own; it does not disguise a change of goal or a substantial expansion of the work as one more technical detail.
That agreement has three clear parts:
- which result I asked for;
- which decisions the worker may make along the way;
- which observation really requires changing the scope.
This does not mean scripting every command in advance. The opposite: the agent needs room to execute, and I need confidence that it will not use that room to appoint a new project.
If a real blocker is found, show it and tie it to the necessary rework. If an optional improvement is found, write it down and come back to it separately. Not every good idea has to become my current task immediately.
An agent has to be able to finish
We are used to discussing whether AI can write complex code. I am more and more interested in whether it can stop inventing additional work in time.
Because writing more is not the same as helping more.
An upgrade has a goal. A refactoring has a goal. Rewriting a project can have a perfectly reasonable goal too. But they do not become one task just because the agent found a handsome chain of explanations between them.
I want a result for acceptable money and with acceptable involvement on my part. If I have to stop the worker, re-explain, and hand it back the original request, that work has not gone anywhere. It has just moved into the chat.
In the article about ever-growing rules I already wrote about the false confidence another instruction gives. Here too it is not enough for me to add a prohibition and feel calmer. I need to see whether the original task survives in the actions, in the handoffs and in the review of the result.
I asked for a library bump.
If you decided the whole project has to be rewritten first, show me the necessity. Do not appoint yourself owner of the project just because you know how to write code in it.
For myself, I keep one simple check for next time: where in the assignment is the result I ordered — and where is the plan the agent wrote for itself? If the second is bigger than the first, that is no longer an upgrade. It is a new order, and it should start with my yes.
The first story in reading order from the “Engineering Friction” series — on how agents, tools and processes get in the way of the work they are supposed to speed up. Next: “My Agent and I Share a Clipboard. What Could Go Wrong?”
Originally published at prod.codes.
Top comments (0)