How software engineering is changing
The Times They Are a-Changin’ indeed. Software engineering has changed drastically in the last few years, for better or for worse we are still yet to see. I am lucky enough to have been in a startup since the very first lines of code were written, and I am also lucky enough to see first-hand the changes that AI tools brought to our day-to-day work. In both cases, it is fascinating to see something evolve right in front of your eyes. It gives you perspective on how things (companies and people) move through time, and how every decision leads to something interesting in the future. The company we were and how we worked in 2020, when we just started, is a completely different thing from what it is today in 2026.
Who am I anyway?
My name is Daniel Silva and I work as a Staff Software Engineer at Coverflex. Coverflex is a Portuguese fintech startup serving multiple European markets and our main goal is to improve compensation for both employers and employees. A paragraph from the Coverflex website explains what we do better than I do:
Coverflex is a compensation management solution that brings together every part of employee compensation beyond salary. Benefits, insurance, meal allowance and discounts all rolled into one product. For companies, it’s a way to easily give people more options and value, improving employee quality of life and the company’s bottom line. For employees, it’s the opportunity to unlock more value and create a custom compensation package that anyone can spend as they choose.
As of October 2026, Coverflex has 301 employees worldwide (the vast majority are based in Europe). Of those, there are 50 people working in the Product, Engineering, Design and Data teams (or "Data and Design", there is an everlasting dispute about which one comes first in the PEDD acronym). Our product is available today in Portugal, Spain, Italy and Germany, and very soon in more European markets. It is used every day by more than 25 000 companies and 500 000 people.
I joined Coverflex in 2020 as a backend engineer, right in the middle of the COVID-19 lockdowns. Coverflex was just starting out with a couple of months of existence, and I had the incredible privilege of seeing the first lines of code being written, the first customers buying our product, and the challenges of starting from scratch and scaling into multiple countries.
Coverflex has been a remote-first company since day one. Remote-first plays a very important role in the company culture as a whole. Being remote-first "forces" us to communicate better asynchronously and trust people to do their best work at their own pace. I know the main topic of this text is AI, but as with everything, it starts with people.
People’s agency and the drive to do things
We like to say that every engineer should be a product engineer. This means that we want engineers to have the agency to think about the product they are building in collaboration with other teams. We do not want to mindlessly receive a ticket to be implemented as-is and call it a day. Who writes the issue anyway? How does it come to be? Who decides what and how it gets built?
Engineers should have the agency to do all of that. Of course, this requires, most of the time, collaboration between different people (for example, product managers and product designers thinking at a high level about the product). Engineers are always part of the process of how something comes to exist (or go away because removing features or code is as important as adding them in the first place).
Software engineering was never just about the code you write, it is so much more than that. If I had to summarise it in a single sentence, software engineering is about solving problems (or puzzles, if you want). This requires communication, discussion and thinking at different levels of abstraction to reach some kind of solution (not always the best one, because "best" is always relative and depends on a multitude of factors).
Agency and drive are probably the most important traits we look for when hiring new engineers. We did this even before AI was a thing. Coincidentally, this also makes a perfect fit for the type of engineer I believe can extract the most out of the AI tools we have today.
I usually say that using AI is a bit like going to the gym, you need to put in your reps to get good at it. You need to be proactive in keeping up with new things and improving how you interact with these tools. You also need to get a feeling for what feels right to you. For example, when a new model is released, I look at benchmarks, but I still need to test and use the model to see how it feels in my workflow. Sitting and waiting for your company or other people to tell you what to do and how to do it does not work out in the long run (like having your company tell you which text editor to use). Usually, the learnings you and your team get compound on each other when you share knowledge. Getting better at something can be, weirdly, a collaborative experience.
Experience plays a role, but there is still hope for junior engineers
Recently there has been a lot of discussion about AI "eating" the junior engineers positions, but I don’t think that is entirely the reason. The job market is not getting back to the ZIRP times in the near future, so it is natural that the market feels tougher now to get a new job. We are still feeling the effects of this change. One of the biggest victims of this was engineers with less experience.
Having years of experience allows you to make better decisions with more confidence. It also allows you to navigate problems in a more pragmatic way, leveraging the accumulated knowledge. And this actually translates to how most engineers use AI tools. Making decisions is as important as ever, and decisions keep coming with the increased speed that AI brings. But, I’ve seen first-hand engineers with less experience becoming faster, learning more things outside of their comfort zone and making more and more decisions thanks to AI. And guess what? They have a profile with high agency, drive to learn, curious, ask a lot of questions, write a lot and share ideas, … Companies need to keep hiring more junior profiles, AI is not going to replace them, but give them new tools to improve (and contribute) faster. Having a junior engineer with a different mindset, ideas and opinions, supercharged by AI, can be a huge asset that a lot of companies are missing out.
People run at different speeds
AI adoption is not a uniform thing. People "discover" how AI works at different speeds, and that is not connected to seniority either. I’ve seen examples of less experienced engineers picking up AI tools and evolving their workflows faster than more senior engineers.
Why is that the case? I have not reached any definitive conclusion but, again, the person profile seems to play a major role in this. Engineers with an "executor" mindset tend to take longer to incorporate AI tools compared to other engineers. Which, for me, sounds odd because I would think that would be the first type of engineer that would take advantage of AI to work faster. My main theory right now is that, as I said before, using AI effectively and getting better at it requires experimentation and effort to figure out what works and what doesn’t feel quite right. And sometimes, for that type of engineer, it is necessary to create more structure and guidance to make that happen.
That is why you will see teams moving at different speeds. The engineers on the bleeding edge should help create that structure and guidance for the rest of the team that still needs to walk that path. This could be live presentations, workshops, written and video guides, one-on-one sessions, …
AI is just a tool, you still need to know what you are doing
With great power comes great responsibility. AI is a great way to learn and do new things very quickly. You can jump into a completely unknown code base and start being productive in no time at all. But if you do not understand what you are doing, making decisions and being critical about them is almost impossible. Without the mental picture of the system you are working on, you are flying blind.
I have seen other people (and myself) fall for this trap. Getting out of it can be difficult because you need to set time and space aside to really understand what you are doing. There is no cheat code or quick way out. For me, the best way to fix this is, counterintuitively, to write code or documentation by hand. Just like in school, when I would write down notes with pen and paper to study for an exam, writing code or producing a technical document by hand lets the brain process information at a reasonable pace and build the mental map that is essential for anything that comes after. Doing this will make any AI usage much more efficient in the future.
Another trap that gets annoying really quickly for everyone is when you let AI "speak for you". For me, most of the time, it is pretty obvious when I am reading something generated entirely by AI. It is usually very dense, long, and hard-to-read prose that I quickly lose any interest in reading. And we see it everywhere: in pull requests comments, in RFCs, in Slack messages, … I am not completely against it, just to be clear. I see some useful use cases, if well applied. For example, some of my pull requests descriptions are generated by AI, but always under my strict guidelines that I set beforehand about what the text should contain and how it is presented. In this pull request description example, I’ve had good success by using the show-me skill and adding the following to my global AGENTS.md file:
Always use simple and concise language, either to communicate with me or when writing things down. The main goal is that we communicate in a way that should be easily understood by everyone. Follow the guidelines from ISO 24495-1 for plain language.
But even with this, the key is to read what the AI generates and see whether it makes any sense. Writing to communicate with others deserves respect for their time by being clear and easy to read.
AI at Coverflex and my personal choices
In the last few months, Claude Code has been the default choice for almost everyone on the engineering team regarding coding harnesses. But I keep experimenting and rotating between different harnesses like Codex, Pi, Amp or Opencode.
I really like Pi’s minimalist and extensible approach. Having control of my tools and being able to tinker with them is a big plus for me. But I do like trying other tools because they keep bringing new ideas all the time, and I like to get a feel for them (and eventually bring the ones that I really like to Pi myself).
Regarding skills, I try to keep it to the minimum possible. I have been enjoying Matt Pocock’s skills. They bring a sensible approach to working with AI that matches my personal workflow of thinking about a problem, deconstructing it and analysing it from multiple angles, and making a plan for what needs to happen next.
With MCP servers, I try to keep only the strictly necessary and useful ones. For my usual type of work, Linear and Datadog are the two MCP servers that I have always configured in my coding harnesses. Linear is great for writing new issues and reading context from other projects and their issues. I tend to avoid things like Notion connected through MCP because when I tried it, it was just more distraction than useful for the AI agent. The problem is not necessarily with Notion itself but with the way we organise our Notion pages. I would much rather get context from Linear issues than Notion pages because issues are more organised and link to pull requests where we can inspect more code.
Datadog is amazing and sometimes feels like a superpower. Getting insights based on real production metrics, logs and traces is really valuable to me. For example, a few weeks ago I was able to chase down some performance issues on a very critical path in our codebase, and just by asking an AI agent to look at some samples of Datadog traces and give me some hints on where the issues might be and opportunities for improvement, I quickly had a list of a few actionable things that I could work on. Without AI, this would be the type of task that would have taken easily a week or more to investigate and solve. With AI, that week turned into a couple of hours.
But, regardless of the coding harness or any other tool that you might choose, what happens around them (and because of them) is the most interesting part for me.
Monorepos are pretty useful
A few years ago, we had all our services and libraries in their own Git repositories. This was manageable when we had a few repositories to deal with. Over time, we kept creating new libraries for different domains, and repositories piled up. It was pretty common to have to open multiple pull requests on different repositories to implement a feature, do a bug fix, or even update project dependencies.
At some point, we decided that there should be a more convenient way for us to manage our codebase. We decided that a monorepo (using a “poncho project” from the Elixir world) was the right fit for our team. This meant that with a single pull request, we could deliver all the changes that we needed. This does not come free, of course. We had to deal with a more complex CI/CD process and merge queues when multiple people were trying to merge pull requests, …
This decision, even without AI in the mix, was already pretty good for us because it made the work more convenient for everybody. Accidentally, we also created the best-case scenario for AI. Since all of the relevant code and supporting files are co-located in the same directory, AI agents have no problem going through it to find the most relevant pieces for the task at hand. We found that with direct access to the code, AI has a higher chance of producing good results compared to having access only to documentation for a certain internal library or service. Documentation gets stale if not maintained carefully, but code is the source of truth right now (even when the code is wrong, it is still the source of truth).
The importance of the local development environment
For years, we neglected the experience of running the entire backend services on local machines. This happened for multiple reasons. We have access to a staging environment where every merged commit is deployed, and everyone relied on it to run the code they wrote. Also, our system relies on a couple of external providers hooked up to these pre-production environments, but not to local machines, making it hard to run specific features end-to-end. And there are a lot of moving parts that need to be configured and started to make things work. It is a fairly complex system.
I spent months without actually running any service on my machine. I used TDD to develop, and I relied on unit and integration tests to make sure I was doing the correct thing. And it was mostly fine! But fairly recently I saw this post from Thorsten Ball where he just asks for irrefutable proof that what it has done works as intended, and I got curious how well this actually works. So we invested some time (and tokens) to make sure our entire stack of backend services runs on local machines with as little effort as possible. Using mise tasks for project commands, process-compose to orchestrate all of the service processes, and Docker containers for PostgreSQL, LocalStack (to simulate some AWS services) and Grafana/Loki/Tempo (even though we use Datadog for observability, since we use OpenTelemetry, this provides a local solution compatible with Datadog), we got to a sweet spot where we could start and clean up all the services and dependencies with a single command. The remaining challenge was dealing with the external providers the services depend on. The solution is to have local simulators of those services, and you would be pretty surprised to see how effective AI agents are at creating these simulators if you point them at some documentation and the code that interacts with these providers.
Finally, after all of these years, having the option to actually run the software we get to work on every day felt really good. And things got even better when we saw the results of having AI agents using the local environment. The manual testing I was doing on the pre-production environments was now being done automatically by AI (with the help of agent-browser) to prove to me that what it just implemented works as expected. This can catch problems you only see when all the pieces click together in a real running environment. This gives me even more confidence in what I deliver than the regular TDD approach I have used for years.
Remote sandboxes and multiplayer
We all work remotely, but we get “together” frequently to discuss things. Slowly, AI agents have become part of the conversation, where one of us would open Claude Code or Codex and throw some ideas at it or ask for some research. The annoying thing is that when the discussion is over, the only option is to export the conversation and share it with other people. For a long time, we missed a coding harness that was multiplayer, allowing everyone to have access to the sessions, contribute to them and read them later.
A couple of months ago we found a solution for this problem: Amp Code. With Amp, we have shared threads that multiple people can collaborate on, and that was the main thing that drew us to try it out. But we were really surprised by how much we liked remote sandboxes (the orbs feature in Amp) and how it made our collaborative work better. With this, we can collaborate not only on the discussions leading to some code change, but also on the code change itself. It is common to have threads where two or three people are giving input to a session (asynchronously), collaborating with each other and seeing the results of the changes.
On the remote sandboxes, we also capitalise on the fact that we can run the local environment and let AI inspect and act on it. On my local machine, even if I use Git worktrees to have separate checkouts of different branches, I can only run the services for one of them because of clashes between ports and other shared resources. But on remote sandboxes, each is a separate container that is isolated from everything else, which means I can run multiple local environments, one on each different thread of work. With this, I find myself doing much more in parallel than before, and I can bring my colleagues with me on any thread I have going on.
I would say this is a game changer, and I suspect we will see a trend in this direction in the near future.
Adapting our product for non-engineering AI tools
AI adoption goes way beyond the engineering team. Pretty much every team at Coverflex uses some kind of AI tool to automate or enhance workflows. One interesting side effect is that the product that the engineering team builds needs to adapt to this new reality as well.
Let's look at a concrete example: we have a backoffice that is used by Coverflex teams to manage day-to-day operations. It handles queries for lists of records and read details about a certain company/employee/transactions for customer support, handling KYB tasks, managing schools for childcare voucher networks, managing card authorisation rules, … These are real workflows that non-engineers need to work with every single day. With AI, it brought the opportunity for people to start improving those processes, making them faster and more reliable.
Since the beginning, we’ve built our backoffice using server-side rendering, and no REST API is readily available to allow automated interaction via API calls. So, what happened? People always find solutions for their problems! Using the Claude Chrome extension, browser-based automations are now possible. I am surprised by how well this works, even if it looks a bit janky.
But we quickly noticed the side effects of this. Since the automated browser use is not very efficient at some things (for example, getting a list of transactions for the past month with a set of conditions has to go over a huge number of paginated tables), we noticed the pressure on the backoffice service started to grow. We also noticed that frequently this automated backoffice access tripped our rate-limiting rules. For AI itself, parsing HTML is not very token-efficient, especially if you are doing it all of the time, nor is it reliable because some rules might be based on element classes or IDs that can easily get changed over time, breaking existing automations.
The solution is actually pretty straightforward: build a proper REST API that exposes the functionality needed for these workflows. As a bonus, if we build a well-structured REST API, building an MCP server is easy because we can plug it into the same functionality the API exposes.
The lesson here is that we need to think more and more about non-engineering teams adopting AI tools and give them a good environment and resources to have efficient, automated AI workflows. What we build (even for internal use) needs to take into consideration whether it fits into AI tool usage and plays nice with it, because everyone wins.
Accepting contributions from non-engineers
This is a very sensitive topic nowadays. Personally, I have mixed feelings about opening the gates to non-engineers with no knowledge of our services, codebase, or engineering culture to contribute through pull requests.
The first reason I feel this way is that, at the end of the day, someone on the engineering team always needs to review pull requests. Reviewing something when there is no previous context or discussion is not an easy task. If the volume of pull requests increases, we could end up in a situation where engineers spend most of their time reviewing pull requests outside their scope, or pull requests pile up because no one dares to pick them up.
The second reason, and probably the biggest one, is ownership. Who owns that code after it gets merged? Who makes sure that it is released and everything works as expected, or that there are no hidden side effects? Necessarily, some engineering team ends up owning it. At scale, this could become a real issue.
On the bright side, I feel this is actually not a bad idea, under the right conditions. First of all, there needs to be a process in place where everyone is comfortable making new contributions. Non-engineering people should have some sort of guidelines directing them throughout the process of creating a discussion about the change they want to make and how to make it happen. Sometimes, changes are really small and require no discussion at all (for example, someone at the customer support team needs an extra information on some backoffice page). On other occasions, bigger changes might require input from product, design and/or engineering teams, and in these cases discussions should happen and a plan created. When that pull request eventually arrives for some engineer to review, it is not a surprise anymore, context around it was built and there is enough alignment to make everyone comfortable and confident in moving forward. I’ve seen this exact process happen at Coverflex, and it went pretty well, to be honest. Small changes that had a big impact on the daily lives of our non-engineering colleagues happened because of this.
The big mental toll of AI usage
The big elephant in the room. There is a cost for AI usage beyond what you (or your company) pay for tokens. I have discussed this with several people, and there is a common feeling of being more mentally exhausted at the end of the day when using AI agents.
My main theory is that context switching has always been hard and more taxing than people give it credit for. Just having your day interrupted by different meetings on your calendar is enough to create enough context switching that you physically feel the effects. Working with AI agents, after you send a prompt, there is this gap in time until we get a response back that almost instinctively leads us to open up a new session or check out another session that requires our attention, which most likely has a completely different topic from what you were working on just seconds ago.
This feels powerful and, sadly, addictive. There is this rush of dopamine from being able to juggle multiple things at the same time and getting multiple things done faster than ever before. We do not realise that, slowly, we are draining ourselves mentally. If not done carefully, I suspect this is a new fast track for burnout. I have no numbers (and it’s probably still too soon to measure), but I suspect we will see in the near future a big increase in people burning out and crashing out pretty badly.
And I fear this is not just on engineering. AI tool usage has proliferated across entire organisations, so it is a natural conclusion that this pattern of increased context switching followed by mental exhaustion will start to be felt by a large portion of people exposed to it.
Final thoughts
It seems that AI is really here to stay. It has transformed (not only) engineering for the foreseeable future. There is clearly a time before and after AI got good enough, where it now permeates every aspect of the development process.
Writing code by hand is not going away either. For most of us, it is kind of like a meditation or flow state moment that we really appreciate for what it is (Advent of Code is one of the most anticipated events of the year for a reason). Even if you are creating software in your day job, doing it by hand is still the best way to better understand and get a feel for the system you are working on. But beyond that, writing code by hand is becoming less and less cost-efficient.
I don’t think software engineering is doomed. I still think AI is a tool that requires human taste and ingenuity to make it work. We will most likely need more software engineers because more software is getting created than ever. Infinite problems in the world are waiting to be solved.
Engineers need to keep up with the times and be open to new ways of working with tools very different from the past. This has happened before: more powerful IDEs were created, high-level languages were created, and magnetic tapes replaced punched cards… We can do this again, for sure.
As Bob Dylan said, “wherever you roam, and admit that the waters around you have grown, and accept it that soon you’ll be drenched to the bone, if your time to you is worth savin’, and you better start swimmin’, or you’ll sink like a stone, for the times they are a-changin’”.