Software Engineering Principles That Still Hold Up in an Agentic World - Old Lessons Made New
Published 6/18/2026
The skills problem isn't going anywhere — it's just wearing new clothes. In this episode, I unpack how the lessons we learned decades ago (limiting work in progress, the theory of constraints, test-driven development) are coming roaring back as the fundamentals that will carry you through the agentic shift. The bottleneck has moved, and knowing where it went changes how you should work.
A lot of what we're learning about building with agentic tooling isn't new at all — it's a re-emphasis on lessons software engineers learned twenty years ago, just arriving in a new form. In today's episode, I walk through why the fundamentals are becoming more important than ever, why so many of us feel scattered despite having the most powerful tooling we've ever had, and where the real bottleneck in software delivery has quietly moved. My goal isn't to convince you that your job is now babysitting AI — it's to show you which parts of the work are still squarely yours, and how older principles can make you faster and more confident right now.
- Limiting Work in Progress Is Back: Just because you can spin up fifty agents doesn't mean you should split your focus across fifty things. Orchestrated fan-outs are powerful, but a human juggling agents across hiring, on-call, and a project all at once still pays the same old context-switching tax — and the quality drops while the speed never improves.
- Work Deeper, Not Wider: Instead of spreading yourself shallowly across more tickets, run multiple sessions on the same domain. Write a competing or adversarial version that critiques your assumptions, develop better documentation, or capture what you're learning as a reusable skill. Depth beats breadth.
- The Scattered-Engineer Epidemic: Engineers are burning out faster, not slower. We have the capacity to push more through the pipeline, so we're getting handed (or choosing) more than we can carry. Reducing parallelism often holds your delivery speed steady while dropping your cycle time and raising quality.
- The Theory of Constraints, Revisited: Treat your software development lifecycle as a pipeline with a bottleneck — and if you can't find one, you've optimized one part too far. Writing code used to be the choke point, so we spent enormous energy de-risking work before it ever reached an engineer.
- The Bottleneck Has Moved: When production gets cheap, it's no longer worth heavily de-risking upstream — which is why engineers are picking up more experimental, proof-of-concept, discovery work, and product folks are prototyping with these tools too. The new constraint isn't writing the code; it's verifying the agent didn't ship something broken.
- Verification Scales With Your Effort: The more an agent produces, the bigger the pile of PRs, MRs, and outputs waiting on human review. That backlog is the new bottleneck — and skepticism is creeping in because we're not even sure our tests are sufficient to verify what the agent built.
- Why TDD Fits This Moment: The honest question isn't "Can I trust the agent?" — it's "What verification loop do I need to build so I can trust it more?" Clear requirements feed a clear testing loop: write the failing test, let the agent write the code to turn it green, and you bridge the gap between requirements gathered and requirements met. It's not as simple as "go write a test," but it's a strong fit for where we are right now.
- Episode Homework: Go dig into the fundamentals — limiting WIP, the theory of constraints, test-driven development. Find the old lesson that still applies to your workflow today, bring it to your team's flow, and email me about what you discover.
🙏 Today's Episode is Brought To you by: Unblocked
Your coding agents probably have access to your codebase — and maybe your tools and MCPs too — but access doesn't mean context. Agents don't know your architectural decisions, your team's patterns, or why your API is shaped the way it is, so Claude ends up building a new model when it should have changed an existing one, and you're left clawing back bad outputs and burning tokens on correction loops. Unblocked is the smart context layer your agents are missing. Instead of dumping everything into a giant context window, it builds reasoning over shared context — turning code, docs, tickets, and conversations into actionable context so engineers move faster, agents make better plans, write higher quality code, use fewer tokens, and need fewer corrections. If you're running Claude Code, Cursor, or any agentic workflow, go check it out. Free three-week trial at getunblocked.com/developertea.
📮 Ask a Question
If you enjoyed this episode and would like me to discuss a question that you have on the show, drop it over at: developertea.com.
📮 Join the Discord
If you want to be a part of a supportive community of engineers (non-engineers welcome!) working to improve their lives and careers, join us on the Developer Tea Discord community today!
🗞️ Subscribe to The Tea Break
We are developing a brand new newsletter called The Tea Break! You can be the first in line to receive it by entering your email directly over at developertea.com.
🧡 Leave a Review
If you're enjoying the show and want to support the content head over to iTunes and leave a review!
Transcript (Generated by OpenAI Whisper)
surprisingly or unsurprisingly depending on your philosophy a lot of what we're learning about building with agentic tooling and uh the the new workflows we're using a lot of it is reinforcing reinforcing lessons that we've learned in the past. It's reinforcing the practices that we've learned in the past. It's just doing it in a new way. In today's episode, we're going to be talking a little bit more about some of those lessons that we have learned in the past that are coming back around and becoming as important or maybe more important than ever to really understand the fundamentals of. And hopefully in this discussion, you'll get kind of a reaffirmation of the important important parts of your job that are not going anywhere that still require you to pay close attention to those fundamentals. My name is Jonathan Gautrelle. My goal on the show is to help dream developers like you find clarity, perspective, and purpose in their careers. So much about what we're doing in this job as AI takes off. This has been the topic of conversation for many episodes now. And hopefully you all understand my intent here is not to jump on the hype train. It's not to make you feel like, you know, that your job as an engineer is now basically babysitting AI. That is not the future of this job. In fact, a lot of what we're learning, a lot of what we're facing in this job, a lot of what you're going to face going forward is a reiteration. It is a revisiting. It's a re-emphasis on lessons that were learned in the earliest days of software engineering, perhaps even before software engineering. Lessons that were learned in knowledge work before that, in engineering work before that. And I want to talk about some of those lessons. I want to talk specifically about some of the things that we're seeing pop up as it relates to human behavior. Right. And then also as it relates to the lifecycle of software development. it. Okay. And so a lot of what we're recognizing, then we being me, my colleagues, people in the industry, if you go and watch other kind of strong voices about this topic, about what, you know, what skills are going to be necessary in order to succeed and, you know, live past this AI boom and into the next phase of the industry, what's going to be necessary. The lessons that we're learning about this is that a lot of the stuff that we had learned before is coming back. I'll give you the first example. The first lesson that we should be reiterating is limiting work in progress. Limiting work in progress. So there is some belief that because AI can multi-thread, because we can spin up 50 different agents all at once. Quite literally, I ran a workflow the other day and it fanned out to 50 different agents. That therefore now we can get a lot more done in parallel. parallel, right? You can do, you can send an agent this way and that way and the other way, and you can do a lot more. And there's some truth to this, right? There's some truth to this. In particular, if you have some kind of orchestrator that's running those fan-outs, then yes, there is some kind of parallelization that's going to happen inside of that orchestration and you were kind of sitting back and you're not having to necessarily orchestrate all that parallelism, right? So this happens, for example, in cloud code. You tell it to go research these 10 different things and it will fan out agents to go do that. Okay, you can literally tell it to fan out agents to go do that. Powerful stuff. What doesn't work, what doesn't work well at least, is splitting your focus amongst so many different things. And what this looks like is saying, okay, you know what? I've got as many agents as I can fill up and answer, right? I'm going to, you know, fill up my queue and when that one's running, I'm going to go get the next ticket and run a second one. And I'm going to go get the next ticket and run a third one. And then I'm going to kind of loop around and keep answering questions from these agents, right? This is a work pattern that I've seen happen. And there's some tooling that supports some versions of this. I personally, I have a handful of agents open at any given time, and I'm going between them and answering questions and trying to keep things moving. But what I've noticed with myself, with others, is that very often this doesn't necessarily speed up my work. It doesn't really improve the quality of my work, if, especially if the fracturing that I'm talking about here between these days, if they are, or between the agents and the work you're doing, if they're totally in different domains, if they're jobs that I'm trying to do across multiple teams or across multiple concerns, maybe I'm talking about hiring in this agent, and then I'm talking about a specific project in this agent, and I'm talking about on-call support and another session, jumping between these things, I still have to, as a human, context switch. And so there is a huge kind of loss that happens when I'm spreading my context, when I'm spreading the context across so many sessions, my mental context, I can't keep up with that many different things. There is a limit. There is some number that I can keep up with, and everybody has a slightly different number, but there is a limit and that's the key word. That's the key word. When I go past that limit, the quality of my work degrades, the speed doesn't get any better, right? So my delivery ends up delaying across the whole cohort, right? And I have switching costs. All of this should sound familiar if you've been doing software engineering for very long at all. Switching costs, limiting work in progress, these are things that we learned 20 years ago. a long time ago, early in our careers, right? This is stuff that we've known for a long time, that humans are not good at context switching. We've talked about context switching on this show before. One of the very first episodes that we talked about is focus. And so while the picture is changing, right, we can have something doing background research, for example, and we switch context. And then there's something good that's, you know, something productive, useful, good that It might be happening in that session and we're not having to necessarily pay close attention to it. If we are actively trying to push forward on multiple things just because we can, just because we can kind of set an agent off and sit back and go to another agent. And there's something inside of us that says, well, sitting and waiting for the agent to return is a waste of time, right? That's the intuition that we have. And so if that's a waste of time, then, well, certainly working in multiple work trees would be better. You know, working across multiple tickets, I can get more done, right? This intuition is, you know, it's essentially like an optimization problem. But it's ignoring the parts that we talked about, the kind of slow parts of our brain that require context switching. switching. And what I would argue is a better way to think about this is work deeper on the fewer things. So for example, okay, let's say you want to do multiple sessions. That's fine, but do multiple sessions around the same domain, right? Do multiple sessions that are related tickets, maybe if you're still working in that kind of paradigm. Do multiple sessions that are, Or, okay, I'm going to write the first version of this, but I might write a competing version or an argumentative, I'm not sure I'm even saying it right. Anyway, there's adversarial is a better word, the kind of trending word here. It's an adversarial agent. Write an adversarial version of this that says, hey, I'm making some assumptions over here, watch it and then critique it. And then suggest improvements. And then you can take, so the idea being like, instead of wasting your time by going to multiple tickets or wasting your time by sitting back and waiting on an agent, you can do deeper work on the same thing. You could start to develop better documentation. You could write a skill about what you're learning on this ticket. There's more that you can do that's deeper deeper rather than trying to spread your spread yourself shallowly across so many other tickets. Okay. So that's the first lesson that's coming back up over and over is limiting your work in progress, protecting your focus. Um, I'm noticing that people are burning out a lot faster. They're getting scattered a lot faster. We have the most powerful tooling that we've ever had access to as engineers, and we feel more scattered than ever. This is anecdotally, at least. I've noticed this kind of sense of frantic scatteredness, right? Because most engineers are getting handed more to do, more to throughput. We have the capacity to put more through because of this agentic powerful stuff that we have, but we're feeling more scattered because we're having to carry too much at once, or we're choosing to carry too much at once. And it's very possible that we have just the same delivery speed if we reduce some of that parallelism and we limit our work in progress, we focus on doing deeper, more quality work one piece at a time, right? And very likely, we're going to see our cycle time on that stuff go down. The time that it takes to pick up a piece of work to finish the piece of work, it's Cycle time will go down, quality will go up. These are things that have been true for a long time. They've been true for a long time. There's other lessons that have been true for a long time. I want to talk about them. Right after we talk about today's sponsor, Unblocked. This is the last episode in this run of sponsoring from Unblocked. I really hope that if you haven't yet, I want you to go give it a shot. I want you to go check out Unblocked. Your coding agents probably have access to your code base, probably more than just your code base. Maybe you've connected the tools, MCPs, maybe you're building skills, but it's not easy to keep up with everything. And access doesn't mean context. If you're like me, then you're trying to build this context all the time, building new skills, trying to deploy your agents in more narrow pathways, that kind of stuff. stuff. Agents are not very good at reasoning on their own across a huge landscape of MCPs and knowledge base and that kind of stuff. They don't know your architectural decisions. They don't know your team's patterns. Why is the API shaped the way that it is? What kinds of rules, architectural rules do you have in place? A lot of times, Claude will go and build new models when there's actually an existing model that it would have made sense to just change the existing model. This is a problem with context and some of the reasoning that Claude makes. And so you end up having to go back and claw back some of this stuff that Claude is creating. It delivers bad outputs, and you're going to end up wasting tokens dealing with all that. Unblocked is the smart context layer that your agents are missing. And instead of just ingesting all that data and getting lost in this gigantic context window, Unblocked is building reasoning over shared context. text. Unblocked turns code docs, tickets, and conversations into actionable context. So engineers move faster and agents make better plans, write higher quality code, use fewer tokens, and require fewer correction loops. So if you're running Cloud Code, Cursor, or any agentic workflow, if you're not, by the way, go start. It's good to learn this stuff. It's very likely that your work is headed that direction, whether you want it to or not. But if you are, then go Go and check out Unblocked, especially if these problems are hitting your team or hitting you. Go and check it out. It's worth a look. Free three-week trial at getunblocked.com slash developer T. That's G-E-T unblocked.com slash developer T. Thanks again to Unblocked for sponsoring today's episode of Developer T. so uh this is um a huge part of what we're learning a huge part of what we're learning is that some of these patterns that were established before we need to pay attention to them and adapt them, but not abandon them, right? So we talked a little bit about, you know, the human side, how we protect our focus, how do we make sure that we're not fragmenting across too many things just because we have the tools that can fragment. So, you know, holding a bunch of stuff in parallel, just because we have those tools doesn't necessarily mean it's the right way to work, right? So similarly, we have these kind of older ways of doing software development life cycles. So whether you worked in an Agile or Waterfall kind of format in your software development life cycle, there's some form in, you know, let's say a year ago where you would have some kind of discovery, right? Some kind of like definition, requirements gathering, planning, specifications, all things, you know, opportunity sizing, all this stuff that happens generally before the work begins, right? And sometimes if you're working in an agile environment, it happens kind of continuously with the work, but there still is some kind of cycle, right? A cycle being, okay, we're going to get some information. We're going to make a plan based on that information, creating new information, right? Adding clarity, refining something. So this is generally what we refinement. We take some kind of requirements and we refine them to make sure we've answered edge cases and we deal with all those things. And then we're going to actually go and execute on that and deliver it, test it, and make sure that it's getting out to production and that we have some kind of observability so that if we have some kind of failure later on down the road, or if there's some kind of a new edge case that we didn't test for, we didn't predict would happen, we can recognize it. And then that whole cycle starts back over, right? The new edge case creates new opportunity, and we deal with that in our requirements gathering and specification work. This is largely, there's still huge pieces of this that are still true. And hopefully you see this in your work. The software development lifecycle, however you formulate it, however you formalize it, there's still a lot of this that's true, but there's parts and pieces that we need to adapt how we execute on it. Okay, so in particular, where does this whole thing speed up, right? Where do things get easier? Where do they get, you know, much faster? So that if you think about this whole software development lifecycle as a pipeline, line, then you're looking at, we're using kind of very old school methods and mindset to think about pipelines. And this comes from manufacturing. It comes from a theory of constraints. We talked about that quite a bit on the show. And the theory of constraints basically says that at any given point, if something is going through a life cycle, it's going through a pipeline of some kind, that there will be a choke point, no matter what, right? If there isn't a choke point, then create one. Think about this, okay? If there isn't a choke point, then create one. In other words, try to make any part of that better, okay? And if you can visualize this, you visualize it's it's a bottleneck, right? The visual is that, you know, if everything moves through at approximately some speed, you can imagine that that's a certain size pipe, okay? And if something gets faster, then the pipe is bigger, so more can go through. Well, if something's slower, then the pipe is smaller. It's a bottleneck. All right, so once we find a bottleneck, then we redirect resources to to the bottleneck to either relieve the bottleneck, in other words, you know, increase the speed at that point, or we try to optimize around it, right? If it's, if we can't increase the speed, then maybe we can add resources to that. Maybe we can, you know, optimize it so that we never are, you know, post that bottleneck. We're not creating a secondary bottleneck or we're not creating some kind of, you know, pile up in front of the bottleneck and causing more problems. Additionally, we can optimize the rest of the pipe so we can remove resources from more powerful or faster parts of the pipe. So we can say, OK, well, if we know that this thing is just so slow, then we don't necessarily need all of our horsepower. We don't need as many people upstream from that trying to turn things through quicker because we can't go any faster on that one spot. Same thing downstream. stream. It could remove resources from downstream because they're essentially sitting idle. Okay. So, um, so that's the basic theory of constraints. And what we've seen is that what used to for many, uh, for many organizations used to be the bottleneck. This is kind of what, by the way, unblocks talks about this, this idea that writing code is no longer the bottleneck. Um, what used to be the bottleneck is, is the production process, the actual writing of the the code, the translation, and not just the writing of the code, but the parts and pieces of delivery, right? That engineer takes over something. And so we optimize our software development lifecycle to reduce the number of things that would get to the engineers that could somehow get canceled, that would, you know, potentially would go in a different direction. We try to reduce variability before it gets to the plate of the engineers. and what this yields is a lower risk throughput through engineering. We're trying to make only the bets we feel really good about are the things that would land on an engineer's plate. It's only worth doing for sure. Then if we make that very cheap, if we make the production process process a lot easier. And we're not talking necessarily about the testing. We'll get to that in a second. But we talk about the production process. If we make it much cheaper, then it becomes a lot less important to de-risk upstream. In other words, we could have something that lands on the plate of an engineer that's a little less worth doing and still do it without having to risk a lot because it's not very expensive to do. So what this means is a lot of the energy that we used to spend in de-risking things before they got to engineering, we don't necessarily have to spend as much of the energy. We don't have to slow things down in discovery as much anymore because once they land on engineering, if it turns out that it was a little bit wrong or if it turns out that we want to cancel that, there's not a lot lost. We don't end up putting a bunch of money and then throwing it in the trash, right? And so that begins to kind of spread the risk and spread the discovery process a little bit further into engineering. And now we're starting to see that engineers are tending to have a little bit more kind of experimental responsibility, a little more testing responsibility, a little more get started a little bit earlier in the process. Let's do engineering as discovery, right? We're going to do some more proof of concept kind of work. And we also are seeing that product managers and folks that were working upstream are starting to do a little bit more of this as well. They're picking up some of these tools because we're kind of democratizing some of the simpler building tools to kind of test out ideas, right? To get closer to handling and creating little prototypes and that kind of stuff. And this is really helpful if you look at it through this lens of the bottleneck. It helps you understand why is that happening? Not just bottleneck, but of kind of this pipeline theory, right? So what is the fundamental that we're seeing happen? Again, first, the fundamental is the theory of constraints is at play. We can see that happening in almost every organization that's paying close attention. But we're also seeing that there's another new bottleneck that a lot of engineers are feeling. And this is happening if your boss or your boss's boss is coming to you and saying, well, shouldn't we be able to move a lot faster now? This, you know, we have cloud code. I'm paying, you know, quite a bit in token costs. Why are we still taking so long to deliver software? Most organizations are probably going through this, right? Right. And the average engineer, at least the ones I've talked to, the ones I've observed, the average engineer is going to say it's mostly a problem, not of writing the code, but making sure that we don't ship something that's broken. Right. We're getting the stuff mostly right. We're getting the, you know, the build and the requirements are getting mostly, mostly mostly correct as to what we've created but a lot of times what's happening is we're missing some kind of requirement that a human may interpret during the moment but the agent is not interpreting during the moment correctly so if we miss the requirement upstream and it's hard to predict what we're going to miss upstream then when do we catch it we catch it after the agent has done the work and when we're in some kind of verification state right we're reviewing the code testing it, we're running some kind of post-agent human verification step. So this is a new bottleneck. This is a new bottleneck because it means that all of the work that an agent does, it scales to our effort to humans. In other words, the more we do with an agent, the bigger this bucket gets and the much higher restriction we get on the backside of that bottleneck. So when you have a bottleneck where you have a very fast step in front of it, you end up with this big stock, right? And the big stock is all of those MRs, all those PRs, you know, all of those tickets that are piling up for you to go and review. All of those skills that you haven't incorporated into your quad skill base, right? And so there's a lot of new review work that we're having to figure out how to churn through. Drew. Okay. So the fundamental that we're looking at here, the lesson that we learned a long time ago is about building confidence in what you're building. How do I know? How can I understand and verify that what I've made solves the problem that I'm observing? And previously, there was a lot of ways that we tried to tackle this, right? There's The biggest kind of general category is testing, though, okay? Testing, lots of different types of testing. There's unit testing. There's integration behavior testing. There's kind of systems integration into in-tests. You could also look at chaos testing. So these are things that are kind of building dynamic situations on your behalf and then seeing what happens. And then, of course, there's manual testing. And what we've done is we've kind of, we've moved into a new phase of software engineering, but we haven't kind of elevated our testing processes to support it. So instead of being able to rely on clear testing to trust what the agent is building, we are essentially practicing skepticism because we're not even sure if the tests themselves are sufficient to verify what the agent has done. This is a very broad strokes. Okay. So what we're learning and what I think you'll learn as you continue through your agentic coding, you know, onboarding, many of us still feel like this is early days in this, right? Right. Which what you will learn most likely is that there is some kind of loop verification loop. And writing those requirements, getting those requirements really correct up front. Right. And spending the time there. Is going to feed your testing loop. Right in this middle bucket, we have, you know, context shaping. shaping. We have all of these things that make the agent do a better job, and it's only going to get better with new models, most likely. Certainly, on average, we'll see improved adherence to requirements, etc. And so we have all these requirements going in, we build stuff, and then we verify that the requirements have been met. You see this bridge. You see the bridge between the requirements that are gathered and the requirements getting met. This is essentially This is essentially returning to test-driven development. If you write a clear test, your agent writes the code to accomplish that test. If you've covered the test cases, then you have much higher confidence that your agent is actually doing what you've said it should do. Now, the question you should be asking yourself is not, can I trust the agent? Instead, it is, what do I need to do? What kind of test? What kind of verification loop? What kind of feedback system do I need to create to begin trusting the agent more? When could I get to the point where I've reduced the bottleneck of my manual testing enough that I feel comfortable shipping things that the agent wrote? This is the next, in my opinion, the next kind of frontier for software engineers to improve their delivery, especially improving their delivery speed. And it's not easy, just to be clear. It's not as simple as go write a test. That would be underselling the complexity here. Every organization is different. Your testing environment is very different. Trying to deal with things that happen in prod that are hard to simulate and staging, that's different. So there's a lot to solve here. there's a lot to figure out but that is the next bottleneck and it again it returns back to this same story that we had before we want to be able to trust that whatever code i wrote whatever code my teammate wrote whatever code somebody five years ago wrote is not breaking stuff today and we do that through something like not necessarily always pure tdd but but it's a pretty good fit for our current moment in agentic workflows. So if you haven't learned a lot about TDD, now's a good time to go learn. Go learn about the fundamentals of that, right? But what exactly is it? Very basic idea is that you would write a test that fails. This seems counterintuitive, right? If you're not doing test-driven, then that's the driven part. If you're not doing test-driven development, you might write a test that verifies what you've already written in code. Because you trust yourself to write the code and then, okay, in order to like cover and make sure that that doesn't break, I'm going to write a test that would break if that code wasn't there. Instead, with test-driven development, you're creating a test, you're creating a requirement and you're fulfilling the requirement with your code to make that test turn green. All right, so there's a lot of things that go along with test-driven development and specifically with that ordering that fit well with this SDLC, this lifecycle of development today. Thank you so much for listening to today's episode. There's a lot of other lessons that we've learned in the past that still apply today in both soft skills and hard skills. And I'd encourage you to dig into those fundamentals. You're going to find great kind of gold mines of information that can still apply these fundamental ideas. Most likely, there's something in there that still applies to your work today. Go and find it and apply it to your workflow. Apply it to your team's flow. And I'd love to hear about it. You can email me, email me at developertea.gmail.com. Leave a comment on YouTube, leave a comment or leave a review in iTunes. You can also join the Developer Tea Discord community. Head over to developertea.com slash discord to join that. Thank you so much for listening. Thank you again to today's sponsor, Unblocked. Head over to getunblocked.com slash developertea. You're going to have better context, three weeks free trial, and go find out what kind of context you're going to have. That's getunblocks.com slash developer T. Thank you again to Unblocked for sponsoring today's episode. Thanks again, and until next time, enjoy your tea.