This post is based on my talk “¿Dónde quedan las buenas prácticas de desarrollo en tiempos de IA?” (in Spanish), which I gave at Commit Conf 2026. The recording is on Commit Conf’s channel.

I’ve been in this industry for about 30 years, and I’ve been working seriously with AI since 2024. That’s not long, but long enough to have some opinions about what happens to the practices we’ve spent decades defending.

A warning before anything else: don’t take my word for it. Run everything here through the filter of your own context. Critical thinking has always mattered in a profession full of hype, and it matters more now. This is a disruptive moment, there are lots of stimuli and lots of interests at play, and if we don’t think about how we work, someone else will do it for us. Some of what follows may also be out of date within a few months.

Two disruptions, and a third one

In 1847, in Vienna, puerperal fever was killing a horrifying number of women after they gave birth in hospitals. Ignaz Semmelweis noticed that the hospital had two separate wards. In one, midwives attended the births and did nothing else. In the other, the births were attended by doctors who also performed autopsies and who knows what else. His proposal was as disruptive as it was simple: doctors should wash their hands.

The medical community came down on him. “My hands are clean, what are you talking about?” Time proved him right, but back then he was pushed into ostracism.

The second one is from our own industry. In the 1950s, programming meant writing machine code. Grace Hopper argued that people should build software in a language humans could understand, and she led the creation of the first compiler. The answer she got was the one you’d expect: performance will be terrible, it’s not optimal, anything you do with that I can do better in machine code. We know who won. Hardly anyone today deals with machine code, not even most people writing firmware.

Grace Hopper in her US Navy uniform, seated in an office in front of framed pictures of sailing ships

Now jump to the present. In March 2025, Dario Amodei, the CEO of Anthropic, said AI would be writing 90% of the code within three to six months, and essentially all of it within twelve. In January 2026 he said we were six to twelve months away from AI replacing software engineers.

I don’t want to put him on the same level as the other two. Semmelweis and Hopper were trying to move their fields forward. He wants to fill his pockets. But, for better or worse, he’s starting to be right. In March 2025 those claims sounded far away. Today I see plenty of companies and teams, and you don’t have to go to Silicon Valley to find them, where 90% of the code isn’t written by hand. Whether engineers disappear, I don’t know. I don’t have a crystal ball, and he doesn’t either.

What I’m sure of is that this changes everything, and we can’t be the doctors refusing to wash our hands.

Why we have good practices

Depending on your level in management, you could boil it down to “we want good practices so the code is sustainable and we make more money”. I’d rather stay at a high level of abstraction and say that we apply good practices to have an impact on something specific:

  • Code readability, error rate, maintainability
  • Development speed, feedback loop, developer experience
  • Collaboration between teams, onboarding, traceability
  • Testing, technical debt, sustainability, reuse
  • Performance, cost, innovation, quality of the final product
  • …and many more

Sometimes we just want a new hire to be productive as soon as possible. Other times we want readable code so our future self doesn’t hate us. All of them come down to the same thing: making the space we work in more habitable. Habitable at the code level, and sometimes at the human level too, because some of the messes we leave for our colleagues aren’t very humane.

How we used to decide

So how did we decide which practices were good, and which of them applied in our context?

How much does it cost? In many places, that was the whole question. I’ve worked at a company where tests were a separate, optional line in the budget. More than 20 years ago, I worked somewhere whose reason for not investing in quality was that it would hurt the maintenance contract they hoped to win afterwards. That’s already questionable ethics.

Hype. Look at the agenda of any conference over the years. I still remember events taken over by Kubernetes, by microservices, by the technology of the moment. We’re too old for JavaScript jokes, so I’ll skip that one.

I like it. A close relative of hype. “I don’t program in that language.”

What should drive the decision is weighing cost against benefit. And I don’t only mean money. I mean how much it costs to have an impact on one of those areas, and what we gain from it, whatever the area.

And in the age of AI?

Where you are on the scale

At the same conference, Edu Ferro gave the keynote, and he let me borrow a slide that didn’t make it into his talk: a developer laziness scale.

  • 0%: you write every line yourself, and search Google, Reddit, and Stack Overflow when you’re stuck.
  • 20–30%: the AI writes code, but you only use it for ideas and then write your own.
  • 50%: the AI writes the code, you read every line carefully, and you almost always adjust something.
  • 80%: you write a prompt, the AI writes the code, and you skim it to see if anything looks odd before pushing.
  • 100%: you write a prompt and push to production without looking at the code. This is what people call vibe coding.

If you’re at 0%, nothing in this post applies to you. Go back to sleep. For everyone else, it depends on where you are, and it isn’t binary: you can be at 100% on one project and much lower on another.

Asier Márquez summed it up another way in a post I recommend, with three maturity levels:

Three maturity levels of AI-assisted development. Level 1, individual prompting: manual context, one-off prompts, human-driven verification. Level 2, harnessed workflows: shared artifacts; skills, rules, and hooks; human-guided execution. Level 3, supervised autonomy: orchestrated loops, automated review and validation, human escalation when needed.

From Asier Márquez’s post.

At level 1 you ask ChatGPT or Gemini something and copy and paste the answer, without even using Claude Code or anything like it. At level 3, agents orchestrate the loop and a human steps in only when needed.

It’s a simplification, but it helps a lot, because where you are changes which decisions make sense.

Watch the feedback loop

One of the things AI changes is our feedback loop. It gets faster, and it can get out of hand, like a hamster spinning its wheel too fast and being flung out of it.

A hamster sitting in the bedding next to its exercise wheel

In the talk, the hamster marks every practice that can derail you. It shows up again later in the post.

We have to accept that the feedback loop has changed, that this affects our practices, and decide which parts of that loop we want to influence.

AI is a multiplier

Following the thread of Edu’s keynote, AI is a multiplier. It can multiply your good practices and how habitable your space is, and turn it into a Zen garden. It can also multiply how uninhabitable it is: more pollution, more bugs, more unmaintainable code. A landfill.

Side by side: a lush Japanese garden with a pond and a thatched pavilion, and a smoky landfill full of scrap and debris under power pylons

That’s why we have to be more professional than ever, and make decisions while leaving the hype aside. Hype is fun, but at work we have to keep it in check.

So how do we decide now?

The same way: weigh cost against benefit. The difference is that everything on both sides of the scale has changed, so we have to reevaluate it all. Some techniques we didn’t apply before, because they gave us too little for what they cost, may now be worth it. Others may be worth less.

What’s new: model, context, and tools

Allow me a very high level of abstraction here; there are talks that explain this in far more detail. When you open Claude Code, Codex, or Copilot, you’re working with a model, giving it context and tools. There are hooks and more, but that’s the summary. It’s a bit like making a cocktail:

  • The coding assistant already brings context (its own instructions, and Claude Code’s aren’t Codex’s), its own tools, and the model you pick.
  • An AGENTS.md or CLAUDE.md file is context.
  • Skills are context and tools.
  • MCP servers are tools.
  • Your prompt is context too.
What each piece of an AI coding setup contributesCoding assistantAGENTS.mdPromptSkillsMCP serversModelContextTools
Everything we configure ends up feeding the model, the context, or the tools. In day-to-day development, we almost never touch the model.

We can call it whatever we want. Calling it evolution when it’s less than two years old is a stretch, but we went from prompt engineering to context engineering, and now we talk about harness engineering. Maybe I’m an old man yelling at clouds, but enough with the new names. A linter in your continuous integration wasn’t harness engineering, and now that you run it from Claude Code it is? Fine.

In essence, nothing changes: we need to be clear about where we want to have an impact. Before, we ran practices through a filter to see which of those areas they improved. Now, on top of all that, we also want to improve the context and the tools we work with. Improving the model itself is rare in everyday development, unless you work with fine-tuned models.

So we have to reevaluate all our practices, the ones we applied and the ones we didn’t, from a cost-benefit point of view, and also look at their impact on context and tools. That’s where you get the most out of AI in development. It’s what moves you to the right on the scale: from a model and a context you paste in by hand, to a system where the AI is partly or fully autonomous, depending on what fits your circumstances.

A tour through the practices

There’s no official taxonomy, and if I drew this map again I might draw it differently. Don’t hold on to the details. I’m not going to tell you that you must apply mutation testing. The point is to look at a few practices, which areas they affect, and how that changes. I grouped them into five areas: knowledge and processes, architecture and design, code quality and testing, developer experience, and integration, deployment, and operations. There are more practices, of course. Nobody needs to tell me which one is missing.

For each practice, I look at three things: whether it got cheaper, whether it improves the AI’s context, and whether it gives it tools. And there’s a fourth mark, the hamster, for the ones that can derail you.

Note that I’m talking about cost going down, not benefit going up. You have to weigh the benefit yourself, because the same practice is worth a different amount depending on the situation of your project.

Knowledge and processes

Onboarding is basic. It helps a person who joins the company, the team, or the project become productive. What a coincidence: good onboarding material also works as onboarding for the AI, and gives it better context. How many people have had an onboarding that consisted of sitting next to whoever had time, not even the best person for it, while they explained how things were set up? If you onboard the AI by hand every time you work with it, you’re wasting your time. With humans, apparently, wasting time didn’t matter.

ADRs (Architecture Decision Records): generating them is much cheaper now. After an interactive design session with the AI, you can ask it to write the ADR from the whole conversation. And once you have them, they enrich the context of future interactions. They already helped humans. Apparently we didn’t care much.

Incident reports help a lot with diagnosis, with understanding later what happened in a system, and with the whole SRE side of things. They also enrich the AI’s context, and you can give it tooling that connects to that information, so that while diagnosing a problem you can ask it to look for past incidents where something similar happened.

Documentation: more of the same, but with a catch. Documenting has become very cheap, so we risk going through the motions: huge documents that nobody reads, and that you end up asking the AI to summarize. That’s the hamster. We need a balance between what we document and how. That’s why lightweight formats like ADRs are so interesting, and heavier, more classic documentation can become a problem.

I wanted to start with this area because I find it curious. All of these were always important, but now that they matter at AI scale and not just human scale, they seem to matter more. You could criticize that, but I’d rather take advantage of it. This is the best moment we’ve had to apply practices we always considered good, but that we didn’t feel legitimate, or backed, to apply where we worked.

Architecture and design

Clean Architecture, Domain-Driven Design, Clean Code, SOLID: all of them are cheaper to apply than ever. But that’s not the main point. If your code is spaghetti, the context the AI receives will be that spaghetti. Context windows aren’t big enough to take all of it, and the fuller the window, the worse the AI does. Suddenly something like vertical slicing gains a lot of strength, because the AI can work inside a slice.

Architecture tests deserve a closer look. They’re much cheaper to write, and they’re a deterministic way to check that the design rules you set are being followed. If your design rules live only in prompts, you spend more tokens, and you rely on the probabilistic side of the AI. Having the rules in its context is fine. It’s much better if you add deterministic checks on top. In an agentic workflow, the agent runs the tests, sees one fail, and realizes it just accessed the database straight from a controller. Telling it not to do something doesn’t stop it. It’s like when my mother says “be careful, don’t have an accident” before I go on a trip. Right, now that you’ve told me, I won’t. AIs work about the same.

API-first design: not every team does it. My anecdotal impression is that it’s related to whether you work with more or less strongly typed languages, though I go back to my earlier warning about my opinions. What’s interesting is that if you design an API first, you’re putting its design into the context, so when the AI generates the implementation it’s more likely, by probability, to respect it. That’s why it pays to understand how context works.

What about the cost?

By now someone is thinking: you keep talking about cost and benefit, but all of this costs a fortune in tokens.

I’m talking about cost in time. This is a convulsive moment. GitHub Copilot changed its pricing the same week as the conference, and Claude Code has changed its conditions many times, and there’s more to come. In a few months, local models may be much more present, and we may run many of these practices locally for cost reasons. Companies that used to set up continuous integration servers may set up servers with agents. So let me leave money out of it, or this would get out of hand. It’s one more reason to reevaluate constantly: whether the time you save makes up for the money you spend will have one answer today and another in three months, with cheaper and more capable models.

Code quality and testing

TDD: people who’ve known me for years might say I was a TDD evangelist. I’ve talked about it a lot and practiced it a lot, and I don’t dare say it’s unnecessary when working with AI. I wouldn’t believe anyone who said it is, or that it isn’t. On one hand, TDD can work well for context and separation, by forcing the model to work in those steps. On the other hand, I see something related to the feedback loop: what used to be baby steps are now bigger babies. There will be contexts where it makes more sense and contexts where it makes less.

Static analysis: cheaper than ever and very useful. Why? Determinism. It’s part of that harness people talk about now. It’s cheap to set up, and then you can run it as often as you want. The recurring cost is computation, which doesn’t worry us much right now.

Mutation testing gets a special mention. Before AI existed, how many of you used it with some regularity? At the conference, a handful of hands went up. Why not the rest? Are you bad developers? No. It’s an expensive technique, its cost-benefit is hard to evaluate, and even though it pays off a lot in some edge scenarios, it was hard to justify.

In case you haven’t used it: mutation testing takes your production code and mutates it. Where there’s an if with an equality check, it swaps it for an inequality. Where you compare with greater-than, it changes it to less-than. It introduces small mutations and runs your test suite against the mutated code. If no test fails, you can change == to != in production code without anyone noticing, which means your tests aren’t good enough. It also produces many false positives, which is part of what made it expensive.

Now, with AI, applying mutation testing, and even iterating to write tests that kill the surviving mutants, is very cheap in time (not in tokens). It helps a lot to improve the safety net, and the safety net matters much more now, because our development cycles are shorter and we generate much more. If you’ve never tried it, try it now. It will cost you very little, and it may surprise you. Then reevaluate when and how you use it.

Smoke testing and end-to-end tests: you might have smoke-tested the happy path in production to make sure a feature or an integration with some system wasn’t broken. Now it’s far cheaper. With skills and agents, you can make it part of your workflow: when you build a feature in a vertical slice, ask for smoke tests for the key processes. Not for everything, because then computation time worsens the feedback loop. It will make the place much more habitable, closer to the Zen garden than to the landfill.

Performance tests have more edges, but they also get cheaper, and an AI iterating on performance can shorten that feedback loop a lot.

Pull requests are the second hamster. Some teams work with them and some don’t, and with AI things are getting out of hand. Fighting huge pull requests was hard enough before; now you get pull requests that go on for miles.

My advice, again about the development feedback loop: if you have an automated AI flow that makes you feel entitled to open a huge pull request because a machine wrote it, you need mechanisms for a machine to validate it. A human can still be in the loop, sure. But you can’t create an asymmetry where a machine produces in a day a change to the code that would take a human a week, and expect a human to review it. If you don’t have quality controls (the famous harness) to review that, don’t do it. Work first on being able to review it. Otherwise, what will the person you send that pull request to do? Approve it and move on.

It happens. At the company where I work now, one team was a pioneer with AI. Early in 2025 they started sending reports of what they’d done during each iteration, with a robot emoji and the percentage done with AI. By the third quarter of 2025 they flipped it and reported the percentage done without AI, because the other number had become so large. That team is great. But three weeks before the conference, in another team and in other circumstances, we had to spend 30 hours of human work because someone decided to merge code into main that they hadn’t even tested by hand. We have to be more professional than ever. We can’t believe the AI did everything right just because we asked it to and told it not to have accidents.

Developer experience

A golden path is very useful, especially with team rotation, because people keep asking: can I use this testing library? Is this allowed? What’s recommended? What are we experimenting with? Putting that in common helps a lot.

An example: we work a lot with .NET, and there was an assertion library everybody used. It was open source, until its license changed and it became paid. We’re not big spenders, so we stopped using it. If you don’t feed your golden path, or something equivalent, into the AI’s context, and you don’t tell it which library you use for tests or give it a skill for it, what will it do? It’ll fill its context with the test code you already have and use whatever is there. If that’s still the old library, it’ll use it. If you don’t tell it, it’ll find its own way and fill the context with whatever it finds.

Software templates and coding conventions: the same applies. Ask the AI for a REST API, and what will it build it with? With whatever REST APIs it was trained on. If you do things differently, say you set up OpenTelemetry a particular way, you’ll spend your time correcting it. Templates for the things you build are now very cheap to make, they’ll save you many problems, and they’ll let you create more services without losing your mind. Remember the microservices hype.

Integration, deployment, and operations

CI/CD and infrastructure as code get cheaper, like the rest.

Observability is very powerful when connected to the AI for diagnosis. The cost of analyzing everything you have, at the observability and tooling level, has dropped a lot. In some situations I just say: this is failing, connect here. I have the Grafana MCP server connected to Mimir and Loki, and whatever stack you use probably has an MCP server too. Then I ask it to diagnose the problem, give me leads, tell me where to look. The amount of work it saves is huge, and it improves the feedback loop a lot.

Supply chain security is the third hamster. Many companies don’t do it, and not doing it today is a disaster waiting to happen. We’ll review less and less code, and generate and iterate on more and more artifacts, so the chances of swallowing something malicious keep growing. If you didn’t do it before, it was for the same reason: cost-benefit. In this case it’s more of a cost-of-loss evaluation, which in the end is the same thing. If you want to go past level 1 on Asier’s scale, you have to do it.

Feature flags and trunk-based development: if our feedback loop gets shorter, if we’re going to ship more things in less time, iterate on them more, and also delete more, anything that makes integrating all that easier is something we have to benefit from. Not because it improves the AI’s context. Not everything is about context or giving it an MCP server, and whether you use a feature flag barely matters to the AI. It matters for how habitable everything around your development and delivery cycle is.

And remember…

This is about thinking. It’s about asking ourselves why we do things, not just following hype or what we like. Sometimes that’s fine, too; this job should also be fun. But we have to reevaluate our profession right now, and be as professional as we can when we choose our practices, what we work with, and how we work.