AI Engineer Europe 2026
The Friction Is Your Judgment
Read the talk
The Friction Is Your Judgment
Agents can produce code faster than teams can understand it. Explicit boundaries, mechanical checks, and focused human review help preserve judgment where speed creates risk.
From a talk by Armin Ronacher and Cristina Poncela Cubeiro
Before you start: Familiarity with pull requests, configuration files, and basic application architecture will help; the TypeScript example requires no agent framework knowledge.
Shipping without friction
A forum post about a security incident acquired an unfortunate social preview. An accidentally deployed configuration change had caused the problem; beneath the incident headline, the company’s marketing image promised: “Ship without friction.” The juxtaposition exposes a practical question for software teams: which obstacles should disappear, and which ones make us stop before a consequential mistake?
Armin Ronacher approaches that question after two decades in software, much of it in open source, including creating Flask. He jokes that the Python framework is so familiar to models that their output now introduces people to it. After leaving Sentry, he had time to explore Claude Code, write about agentic engineering, and hear from other developers experimenting with it. He then started Earendil with a friend in October.
Cristina Poncela Cubeiro, his colleague at Earendil and previously an engineer at Bending Spoons, comes from the other direction. AI tools predate her software engineering career: they helped her learn the work as well as perform it. Together, their experience building with and on agents has brought substantial gains and disappointments. They present an evolving practice, not a settled solution. Two problems recur: psychologically, why is it so difficult to stop prompting and think; technically, why do agents improve some people’s code and worsen others’? Even the prospect of perfect generated code leaves a question about how much judgment humans would still need to exercise.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
When saved time becomes expected output
The shift begins pleasantly. After enough unsuccessful prompts, something clicks: the tools become useful, work becomes more enjoyable, and tasks leave extra time. As adoption spreads, however, that advantage becomes a baseline expectation. Everyone is assumed to have the tools, so everyone is expected to ship faster. The time saved is consumed by additional production, leaving less room for review and deliberation.
Poncela Cubeiro describes two parts of the resulting trap. First, the next prompt has an uncertain payoff: it might finish a feature or add the change that destabilizes the product. That uncertainty encourages another attempt. Second, the volume of visible output makes activity feel like efficiency. The stream of changes crowds out the question of whether this is the right implementation—or even the right work. Once the loop is running, stopping becomes difficult for the person, while the agent may keep exploring files it never needed to read. The human has to retain the agency to interrupt the loop.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Production grows faster than responsibility
At team scale, the same shift changes the balance between creating code and reviewing it. When code creation was the constraint, writing and review capacity were more closely matched. Agents amplify each engineer’s production without an equivalent increase in the engineer’s ability to inspect and understand changes. Pull requests accumulate. At the same time, more people participate: marketing staff can submit code, and CEOs who once worked as engineers can return to coding.
The responsibility does not expand as readily. Engineering teams still have to maintain and operate the result, including changes produced by people whose primary roles lie elsewhere. Machines cannot take responsibility for those changes. When the number of producers outgrows the people able to carry that responsibility, reviews are skipped or rubber-stamped. Small pull requests remain desirable, but the amplification pushes in the opposite direction. Ronacher uses a hypothetical 5,000-line pull request to illustrate the mismatch: it demands careful judgment precisely when its size makes disengagement tempting.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Runnable code can conceal an invalid system
When generating code feels cheap, large changes become easy to request. Ronacher connects the resulting behavior to agents’ optimization for immediate progress: write code, run tests, and unblock the task. A configuration reader illustrates the danger. If reading the required file fails, an agent may add defaults so the program can continue. That looks like recovery locally, but the application may now be operating with settings nobody intended.
Consider a TypeScript configuration loader for a required database URL. Catching a failed read and returning a default URL would let subsequent writes proceed against an unintended configuration. A loader that preserves the failure instead makes the missing or invalid configuration visible before those writes begin:
typescript
import { readFile } from "node:fs/promises";
type AppConfig = {
databaseUrl: string;
};
export async function loadRequiredAppConfig(
path: string,
): Promise<AppConfig> {
const parsed: unknown = JSON.parse(await readFile(path, "utf8"));
if (
typeof parsed !== "object" ||
parsed === null ||
!("databaseUrl" in parsed) ||
typeof parsed.databaseUrl !== "string" ||
parsed.databaseUrl.trim() === ""
) {
throw new Error("Configuration requires a nonempty databaseUrl");
}
return { databaseUrl: parsed.databaseUrl };
}
In Ronacher’s illustrative scenario, the configuration mistake is discovered two hours later, after incorrect database records have already been written. The problem is not merely that a read failed; it is that a recovery path hid the failure and allowed consequential work to continue.
In his experience, these attempts to recover from local failures can produce brittle services. The codebase then grows beyond what the agent can navigate reliably: it misses relevant files and creates a new implementation of something that already exists elsewhere. Each local workaround adds complexity that makes the next task harder. A human engineer may feel discomfort while adding this sort of code; an agent does not provide an equivalent emotional brake. That concern has to enter the process through people and explicit constraints.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Libraries expose a smaller problem
Poncela Cubeiro reports an encouraging correlation: agents tend to do better in libraries than in products. A library usually has a defined problem, features that map onto an API surface, and constraints that bound the work. Its core is often simple enough to understand and extend. Products combine more interacting concerns.
| Concern | Library | Product |
|---|---|---|
| Scope | Defined problem | Interacting requirements |
| Surface | Constrained API | UI, API, permissions, billing |
| Structure | Simple, extensible core | Coupled components and states |
| Agent reasoning | More locally bounded | Requires broader context |
For example, a product’s UI and API responses may depend on permissions, feature flags, and billing state. Those relationships can exceed what the agent can hold in context. An edit can be reasonable in the file being changed and incoherent across the application. The design response is to treat the codebase as infrastructure for the agent: its structure determines how much of the system the agent can see and reason about while working.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Make the flow between components explicit
Modular components help an agent add a feature in one place without disturbing everything else. But module boundaries alone are insufficient: the execution flow also needs clear stages. In an assistant refactor, Poncela Cubeiro identifies three main steps:
- Receive the user’s message.
- Pass the message to the agent loop.
- Handle the output.
These landmarks were clear to her, and the code at each landmark was relatively orderly.
The trouble accumulated between the stages. Agents introduced conversions between types and added information to state that did not belong there. These additions quietly expanded the set of behaviors the application supported, including unexpected and potentially dangerous ones. Making the transitions explicit matters as much as naming the major components: otherwise, the connecting code becomes a place to accommodate conditions that the design never intended to allow.
The rest of the approach follows familiar engineering principles. Use established patterns that align with what models have learned. Keep the core simple and put necessary complexity in explicit layers. Avoid abstractions that conceal intent the agent needs to respect. Poncela Cubeiro cites React Server Actions and ORMs, compared with raw SQL, as examples of where that concealment can occur. This is her argument for inspectable behavior, not a universal prohibition on those tools: an abstraction becomes a problem when it hides the relationship the agent must understand to change the system correctly.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Turn design constraints into mechanical checks
At Earendil, much of this discipline is enforced with linting rules. The first example is a ban on bare catch-alls. There is a small irony in the presentation: the agent had already found and edited the catch-all intended for the demonstration. The larger point is to make undesirable patterns detectable without relying on someone remembering every convention during review.
- One SQL query interface. Keep query access in one place so an agent does not have to hunt across the repository and risk missing a site that also needs to change.
- One UI primitives library. Avoid raw input elements outside the shared primitives so styling and behavior stay consistent.
- No dynamic imports. Keep this form of runtime indirection out of their codebase.
- Unique function names. Make a search identify the intended function unambiguously. If an agent’s grep returns one relevant result, it spends less context on disambiguation and can continue its work more directly.
They are also exploring TypeScript’s erasableSyntaxOnly option. It restricts TypeScript constructs that need runtime transformation, such as enums and parameter properties, favoring JavaScript with erasable type annotations. That does not itself remove every build or transpilation step. The attraction is a closer relationship between the source the agent reads and the behavior being debugged, with less transformation-related indirection when locating an error.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Separate repairable defects from human decisions
Mechanical checks improve what the agent produces, but a person still needs a signal that restores attention at consequential moments. Ronacher’s team built a review extension for Pi around that distinction. Mechanical bugs and clear violations of AGENTS.md belong in feedback the agent can act on. Other changes need an explicit human call-out because understanding their consequences requires judgment beyond the patch.
- Database migrations. A migration’s operational risk depends on locks and the amount of data in production. Ronacher wants a human judgment call before it goes in.
- Permission changes. The intended authorization rules may be under-documented. A plausible implementation is not enough to establish that the new access is appropriate.
An agent can help identify these changes even when it cannot own the decision. The call-out makes the person notice that this is the point to engage.
In the demonstrated interface, actionable findings appear above a separate group of human call-outs. Selecting the action to fix issues would send the first two categories—mechanical bugs and instruction violations—back to the agent. It would not resolve the human decisions below. The linked extension is a mutable implementation, and its current human call-outs are non-blocking attention signals, not an enforced approval gate. A new dependency, for example, raises questions about whether it belongs in the codebase and whether its maintainers are people the team wants to trust. Fast generation does not answer either question.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Use speed where it creates a useful starting point
Issue reproduction is one of Ronacher’s preferred uses of agents. A customer report can become a concrete reproduction case, giving an engineer a much better starting point. Exploring product directions is another useful application, provided the team accepts responsibility for the generated code. His assessment is less favorable for system architecture and reliability, where interactions and consequences matter more than producing a first working version.
Ronacher warns that months of technical debt can accumulate in weeks or days; this is an experiential warning, not a measured production rate. As the mess grows, understanding falls, and honest assessment becomes harder both technically and psychologically. He describes finding code that failed in production, then realizing that he had committed it himself with an agent’s help. The disappointment came with recognizing that the responsibility was still his. Slowing down is necessary to see the actual state of the codebase, including mistakes hidden by the satisfaction of having shipped.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Keep the friction that lets you steer
Some shipping friction is merely annoying and should be removed. Other friction is deliberately designed to make a team consider whether a service is reliable enough, how critical it is, and whether enough people are available to operate it. Ronacher points to service-level objectives, or SLOs, as an established example. More precisely, the operational constraint comes from the policy tied to the objective, such as an error-budget policy. Agent speed does not eliminate those reliability and staffing decisions.
The closing analogy is physical: steering requires friction. Software teams also need points of resistance where experience can affect the direction of travel. A review that prompts a real decision about permissions, a migration, or operational risk is not wasted time simply because the code arrived quickly. Useful friction is where human judgment enters the process.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
From the talk
Official guides, tutorials and API reference for the Flask Python web framework.
Explains the syntax restrictions used to keep TypeScript compatible with type stripping.
Ronacher's review extension separates actionable defects from changes needing human attention, including migrations and permission changes.
Installation and documentation for the extensible coding agent used in the review workflow.
Further reading
- Mario and EarendilArticle
Ronacher discusses Pi, deliberate software design and why quality requires more than faster output.
- Example Error Budget PolicyDocumentation
A concrete policy for slowing feature releases when reliability falls below an agreed objective.
Read the complete timestamped transcript
- 0:00
[upbeat music] Morning.
- 0:15
Thanks for having us. Um, today I wanna talk with Cristina about friction a little bit. Um,
- 0:23
this is, um, a, a social preview that came up automatically when someone submitted an issue, um, to, um, basically, uh, there was... This is a forum post that goes with, um, a security incident that was deployed accidentally.
- 0:40
It was a configuration change that caused the problem, and the social preview post had the marketing tagline of that company, which said, "Ship without friction." Um, and we wanna encourage to add a little bit of friction to it, um, and I'll tell you why.
- 0:58
So who are we? Um, I've been doing software development for 20 years, most of it in the open source space. Um, I have created Flask, which is a Python framework, which ironically is so much in the weights that a lot of people, um, are learning about it now because the machines are producing it.
- 1:15
Um, and I left my previous company that I worked for, Sentry, in April last year, which perfectly coincided with, um, me having time and then obviously Claude Code. And so I fell deep into a hole of, uh, agentic engineering, and I started writing on my blog and, and, and a lot of people reached out to me over
- 1:32
the last year, um, being all excited about this. Um, and then I started with a friend in October, a company called Earendil, where we are trying to make sense of all the AI things.
- 1:44
Um-
- 1:46
Yeah. And my name is Cristina, and I work with Armin at this company called Earendil. But importantly, I am what I like to call a native AI engineer, and what that basically means is that these tools have been around longer than I have.
- 2:00
Um, so what this means is, like, they've been super foundational in, well, how I've become a software engineer, not just because obviously I use them to work, but also because this is the means by which I've learned to do what I do.
- 2:11
And before Earendil, I was working at Bending Spoons.
- 2:16
So we wanna share a little bit from practice, not just theory, but, um, I will readily admit that I don't think I have all the solutions. So we have been building with or on agents for a good 12 months.
- 2:27
Um, we had m- huge leverage and great disappointment, and we, we really keep running into two types of problems. Um, I, I think especially if you listen to some earlier talks at, at this conference, you will have learned a lot about, um, that you should k- keep using your brain.
- 2:43
Um, it's, for some reason, it's really, really hard. So there's a psychological problem, and the other one is the engineering challenge. It's like they, they seem to be producing worse code for some people and better code for some other people, and, like, what is it that actually makes it work?
- 2:56
Um, and so this is really not a solution as it is our part of the journey [chuckles] of how we think so far we have managed. Um, yeah.
- 3:05
So problem number one is the psychology part, which is like, why is it even though everybody told you many times over that you should be using your brain, you should be slowing down, it's actually incredibly hard?
- 3:14
It's just one more prompt and, and we don't sleep that much. Like, what is it that actually makes it so hard? And then would it be that hard if the machines would actually be writing perfect code and we wouldn't have to think quite as much?
- 3:24
And, like, what is it-- Is there something we can do to make this a little bit better?
- 3:29
So I'll begin by introducing the first part of these problems, the psychology problem. And what I want to talk first about is the shift. So I'm sure a lot of us here who have been playing with these tools for a while now experienced this at some point.
- 3:42
We were prompting, prompting, not so good, and then at some point, suddenly it clicked, and they were really, really useful for us. And it was fun in the beginning, and they gave us a lot of extra time, right?
- 3:53
Because not everyone was using them. They were actually tools that made us more productive, that made it more fun to do our jobs. But very quickly, because they were so useful and they got us so hooked, everyone was using them.
- 4:03
And so this kind of had the opposite effect, where suddenly the baseline expectation was just that everyone is now using them, and you have to use them. And so this, this fun and free time translated into pressure.
- 4:15
Now we all have to ship faster and produce more code, and it is just not sustainable to review and to actually have time to think.
- 4:25
And so this leads us to the trap, and I actually think there's two parts of this problem, of this trap, and one of them a lot of engineers have spoken about, and it's that these tools are super addictive.
- 4:36
You never know if that next prompt is going to be the one that makes your product work and you've added a new feature, or if it's going to be that last drop of slop that brings your product crashing down.
- 4:47
And so it's very addictive. We keep doing what we're doing. It's not a great solution. But also most importantly, and I don't think we realize this as much, is that because we produce a lot of output very fast, we are tricked into thinking that we're actually being more efficient, doing more work.
- 5:02
And this is quite the opposite because now we don't have as much time to actually stop and think and decide what we're doing, ask ourselves, "Is this the best way in which I can implement this, or could I be some- doing something better?"
- 5:13
And when you're in this flow, it's very difficult for yourself to stop, and it's definitely very difficult for your agent to stop 'cause it's running around and it's reading files that it should have never even read.
- 5:23
So we are the ones that need to actually have the agency to be in control here.
- 5:29
And one thing that from a-- if you start scaling this from, like, one person to an engineering team, that actually took me quite a while to realize, is that it really changes the composition of the engineering team.
- 5:40
We, we were really supply constrained by creation of code, and so, like, the balance between writing code and reviewing code in engineering teams was usually quite decent. Now every engineer has a multitude of producing power compared to their reviewing power, and so obviously we are piling up on pull requests.
- 5:58
But we are also slowly starting to expand the total amount of humans in an organization that are participating in engineering process. I talked to a lot of engineers over the last year, and increasingly, the, one of the things that came up is like now I have marketing people shipping code.
- 6:12
I have, um, former CEOs ship-- so CEOs that used to be, like, engineers now shipping code again. And so
- 6:20
the, the roles that those people have in the companies also doesn't give them... The-there's not that much, um, um... The responsibility doesn't rest in them. The en- the responsibility still rests with the engineering team.
- 6:33
And so the, the total number of entities, both humans and machines, that are participating in the code creation process outnumbers the ones that can carry responsibility. We are not there where the machine can be responsible for the code changes.
- 6:44
And so that has led to more and more code reviews being skipped, being rubber-stamped. Um, and on the goal to small PRs that, that we wanna see again so that this reviewing process goes, um, this amplification is something that, at the very least, we need to recognize.
- 6:59
And so when you get this pull request that looks really daunting and has five thousand lines of code in it, this is actually when you should be thinking, and that's exactly when it's the most overwhelming, and, and increasingly, we're tapping out of this.
- 7:13
On the engineering side, what we're doing is we are creating larger pull requests. We're creating these massive changes because the, it is free now, right? And the-- If you think about how the agents work, they're really optimized to creating code that runs.
- 7:28
Like, their main objective is write some code, run the tests, make some progress. The reinforcement learning sort of gets this in. And so the, the agents are writing kind of codes that is, is when you as a human, as an s-software engineer, start learning how to write code you wouldn't necessarily write.
- 7:46
So, for instance, you see quite a bit of code that tries to read a config file, and if it doesn't read the config file, it loads some defaults. And as an engineer, you know that's actually not great because I might not notice that I'm reading, re-reading the default config file.
- 7:58
And so I might only discover that I have a massive problem after two hours when I already wrote database records with wrong data. And so these machines, they, they optimize towards making progress, towards shipping stuff, to, like, unblocking themselves.
- 8:13
And as a result, they're creating many more failure conditions than human-written code normally would do. And in part, it's because you as a human feel a little bit of a...
- 8:21
You feel bad when you write code like this. There's, there's something that sort of builds up emotionally in yourself. But the agent doesn't have a reason for this. It, it doesn't feel anything.
- 8:30
And so if you, if you create these services that are sort of hobbling along and they're actually willing to, to recover from local failures, you actually create very, very brittle systems.
- 8:40
And this also means that you're very quickly creating a code base of the size and complexity that the agent itself can no longer dig itself out from. It's going to start no longer reading all the files that it should.
- 8:51
It's, it's creating code in a new file that it has already done somewhere else. And so this, this entire machinery over time creates much more entropy in the source code than you would normally have if, if humans were on it.
- 9:04
And, and a big part of this is that humans feel bad, and the agents don't really have any emotions that they communicate to you.
- 9:11
But as Armin likes to say, don't worry. Not all is lost. We have sou-found some correlation between what the agents really excel at doing and the types of code bases that we actually put them to work into.
- 9:23
And for example, the main example here is libraries versus products. What we found is that for libraries, they tend to excel a lot more. And this makes sense because intrinsically, when you're building a library, you tend to have a very clearly defined problem that you're trying to solve.
- 9:37
And most of the time, you can even map the set of features that you want to build to the API service, and it has very tight cons-constraints. And because this is something that you probably want to build on top of or make accessible to other people, it's likely that it's going to be a very simple core in
- 9:51
which you can then plug into. And on the other hand, products, and perhaps this is a bit more unlucky for the rest of us because we all probably are more into building products, uh, it's much harder because there are so many interacting concerns and components.
- 10:05
Like, for example, you have your UI, your API response. You have different permissions depending on the feature flags, the billing, and so on. And so there's this very heavy intertwining between different components.
- 10:16
And what this means is that for the agent itself, it's impossible to fee-fit all of this into its context window. It has no way to actually understand the entire global structure.
- 10:27
And so locally, the agent tends to be very reasonable, but when it gets to the global scale, it becomes a bit demented.
- 10:34
So what we're proposing here is that just as you would do with any type of system design in the past, your code base has now become infrastructure. And as such, you have to design it in a way so that it is also legible for the agent, and it can make the most of it.
- 10:51
And so this is what we're proposing is an agent-legible code base. And one of the main points that is very clear to all of us, I'm sure, is modularization.
- 10:59
So, like, we have different components, and this makes it easy for the agent to add one feature in one spot without corrupting everything else. But importantly, this also means modularizing your code flow itself.
- 11:10
So, for example, I've been working on some refactoring. We're building somewhat of an AI assistant. And for me, it was super important to understand which steps of my code are actually, like, the main points.
- 11:21
So say, like, you get user message, then I pass the message to the agent's loop, and then I have to deal with the output. And this is where these points are very clearly defined for me, so the code was not as messy.
- 11:33
But it happens to be that between these points, between these steps, that's where the agent tends to add the most fuzz. So it will be parsing between different types.
- 11:41
It's adding things to state that shouldn't be in state. And so you end up with these behaviors that you didn't want to support and that are unexpected and can be quite dangerous.
- 11:51
Another point is trying to follow all of the known patterns because I think we all know by now there's no point in fighting the RL, the reinforcement learning. The more we can lean into it, the better that our out-output is going to be, and it's also more scalable down the line.
- 12:07
Then as mentioned with libraries, like if you have a simple core and you push the complexity to other abstraction layers, then it's going to be easier for yourself and the agent to be able to read your code base, and no hidden magic.
- 12:18
So for example here, uh, using React Server Actions or using ORM instead of raw SQL, what this does is that it hides intent from the agent, and if the agent can't see something, it can surely not respect it.
- 12:32
And so to be more precise, these are the examples of mechanical enforcement that we have been using at the company. And most of these we actually achieve with, uh, linting rules.
- 12:44
So the main example would be no bare catch-alls. Great. [laughs] Imagine that there's an example here. The agent found a bare catch-all, and it was like, "Oh, no, this is bad.
- 12:53
Edited it." But yeah. So we also try to have our SQL, uh, always in one query interface, so that the agent doesn't have to go hunting around the code base finding all of the different places.
- 13:05
Because if it misses one, then you can have breaking behaviors, and again, that's dangerous. We try to have one primitives components library for the UI and not have any raw, for example, input bo- uh, input boxes, uh, so that it's-- we always have one type of styling.
- 13:19
It's very consistent, one kind of behavior. We don't have any dynamic imports. And this may not sound as important, but actually w- we enforce unique function names. And the reason for this is not just more legibility for you and the agent, but it's actually also the token efficiency.
- 13:34
So if your agent is grepping for a specific feature or something in your code base, if it only gets one output, it's going to be much better at continuing with the loop.
- 13:43
And we've started exploring something recently called erasableSyntaxOnly TypeScript mode. And what this does is that your code is basically JavaScript, and it has the type annotations on top. And this means that there's no transpiling direction because there's one source of truth between your actual code and the compiler.
- 14:01
And so when the agent is looking for errors, it doesn't have to have this, like, confusion of, "Oh my God, where am I looking at?" It's, it's much better at finding them.
- 14:11
And so the goal really is get in this loop somehow. Like, get the agent to produce as good code as it can, but you really need to find a way to feel the pain that the agent doesn't feel, and you need to be woken up in a way when you should be looking at this.
- 14:28
And one of the things we have been doing is we build a Py extension for our review needs, where we are separating out the kind of input that normally would go back to the agent.
- 14:37
So this is mechanical bugs. It is where it clearly violated agent's MD. Um, but then we specifically call out the kind of changes where the human's brain should reactivate, right?
- 14:48
It's like we don't think that the database migration should ever go in without a human making a judgment call on this because it very much depends on the locks, the size of the data in production.
- 14:57
Um, if there are permissioning changes, you better think about this themselves rather than the agent because they can be, they can be under-documented. They're just some examples where we learned if we miss it, we regret it.
- 15:09
Um, and you will miss it, but these, these machines can help you find this. And then you see this, and then you actually get a little bit of a hit and like, "Oh, now I have to kick into gear and do something here."
- 15:21
Um, this is what this looks like in Py. Um, you have the, um... On the bottom, you have the human call-outs. On the top, you have what is go- what's basically if you were to end this review and select fix the issues, the, the agent would go back and automatically act on the first two.
- 15:37
Um, but, but this is the moment where I will now go and see, like, is this a dependency I actually wanna have in this code base? Like, do I like the maintainers?
- 15:44
Is this-- Does this work for me? And we obviously like the speed. Like, this is addictive. It is great. We feel there's a lot of productivity. But it is so devious if you start relying on that speed where you really shouldn't.
- 16:00
And so I can only encourage you to find the areas where you, you have this feeling that this is actually not positive. For me, a lot of this is reproduction cases.
- 16:09
Like, when a customer reports an issue, I can, I can have the agent reproduce this perfectly, and I have a really good starting point. Exploring different type of product directions for as long as you commit yourself to doing this, uh, with the code that it generates.
- 16:22
Um, all of this is great, but on the other hand, system architecture, creating reliability in the system, they are not just very good at.
- 16:29
Because we really still have to go slow. It's-- There is so much mess that can appear in a code base in so little time. Mario was already talking about this earlier, but, like, we forget that we are producing months and months of technical debt in the, in the, in a time of weeks, in a time of days
- 16:43
sometimes. And it becomes so much harder to actually understand what's going on in this code base. The-- When the understanding of your own code drops, it is really, really hard, and it's also psychologically hard.
- 16:54
I found some code pieces that actually didn't work in production, and I was kind of frustrated learning that I was the one that committed with the agent and just didn't really see that.
- 17:04
It's, it's a very disappointing experience when it happens, and then you realize that you actually were the one that screwed up. Um, and so it is, it is psychologically incredibly hard to s- to really judge objectively the state of the code base, and the only way right now is to really slow down a little bit on, on
- 17:22
that front. And this, this friction, I know that friction, like every engineering team I've ever worked at said, like, "We need to get rid of the friction in, in shipping," and, and that is true.
- 17:32
Like, there's a lot of stuff that's very, very annoying and shouldn't be there. But if you have worked in large enough engineering org, SLOs are a great system that is intentionally designed to put friction to the engineering process to make you think, "Do I need this reliability?
- 17:45
Do I need this criticality of the service? Am I sufficiently staffed to run it?" And with the agents, we have now gotten this idea that we should get rid of all of this, when in all reality we need of it.
- 17:56
Um, because the friction actually in many ways is what's necessary on a physical level to steer. Like, without friction, there is no steering, and, and that is really necessary.
- 18:07
Um, so you should, you should g- put a little bit more of a positive association to this idea of friction, um, because this is really where your judgment is, this is where your experience is, and you should be inserting that and start feeling it.
- 18:19
Thank you.
- 18:20
Thank you. [audience applauding] [upbeat music]