Páginas

Tuesday, December 30, 2025

New Site: eferro-talks

I've created a dedicated site to collect all my talks and presentations: eferro-talks

It's a cleaner way to find conference material, with filters by year, language, and core talks.

This joins the rest of my projects at eferro.github.io, where you can also find web apps, custom GPTs, curated resources, and development tools.

The goal is to consolidate scattered material into a single access point while keeping each project with its own identity.

Sunday, December 28, 2025

Stop Building Waste: 6 Principles for High-Impact Engineering Teams

As engineers, we've all been there. We spend weeks, maybe even months, heads-down building a new feature, polishing every detail, and shipping it with pride, only to watch it languish. There's no greater professional waste than to develop something that nobody cares about.

This isn't just a feeling; it's a harsh reality backed by data. A huge portion of the software we build is pure waste. But it doesn't have to be this way. By shifting our perspective on what software is and how we build it, we can transform our teams from feature factories into high-impact innovation engines. Here are six hard truths to get you started.

1. Let's face it: Most of what we build is waste.

The first step is to accept the uncomfortable reality that a large percentage of software features go unused. This isn't an opinion; it's a fact. A well-known study by the Standish Group on custom applications found that a staggering 50% of features are "hardly ever used," and another 30% are "infrequently used."

This isn't just a problem for smaller companies. The best tech giants in the world face the same challenge.

The experience at Microsoft is no different: only about 1/3 of ideas improve the metrics they were designed to improve. Of course there is some bias in that experiments are run when groups are less sure about an idea, but this bias may be smaller than most people think; at Amazon, for example, it is a common practice to evaluate every new feature, yet the success rate is below 50%.

If the top companies, with all their resources and data, have a success rate below 50%, we have to be humble about our own ideas. Many of them are flawed. This means we desperately need a process to filter out the bad ideas before we commit to the expensive process of building them.

2. Think of software as a liability to be minimized.

This might sound counter-intuitive, but it's a critical mindset shift. We tend to think of the code we write as an asset. It's not. It's a liability.

Software is "very expensive to build/maintain/evolve." It's only a "means to achieve impact," not the goal itself. Worse, it has "diseconomies of scale," meaning the more of it you have, the more expensive each part becomes to manage.

This creates a "vicious cycle of software." Your team's capacity is used to build new software. This software immediately adds costs: cognitive load, debugging, monitoring, and architectural complexity. These ongoing costs reduce your team's capacity for future innovation. Because this maintenance cost isn't linear (it grows faster than the size of your codebase), you can quickly find your team spending all its time just keeping the lights on. I call this ongoing cost the "Basal Cost of Software", a term borrowed from basal metabolic rate, where each feature continuously drains team capacity, even when not actively being developed.

The goal of a high-impact team isn't to build more software. The goal is to "Maximize Impact" while actively trying to "Minimize Software."

3. Your engineers are your best source of innovation.

For too long, engineering has been treated as a "feature factory." In this classic model, engineers are seen as "code monkeys" who are handed fully-defined solutions and told to just build them.

This model is incredibly wasteful because it sidelines your single greatest asset. Empowered engineers are the "best single source for innovation and product discovery."

Every engineer on a product team should have a "product mindset" and a sense of "product ownership." This means they think about delivering value, not just features. It means they need to understand user problems deeply, which requires direct contact. Engineers should, from time to time, be in the interviews or making shadowing with the customer. Effective product teams are multidisciplinary, involving the "whole team" in the discovery process, not just product managers or designers working in a silo.

4. Maximize Outcomes, not Outputs.

It's easy to measure progress by the wrong things. This is the critical difference between outputs and outcomes.

  • Outputs: These are the things we create. Functionalities, Requirements, Interfaces, Story Points. They are easy to count but tell you nothing about value.
  • Outcomes: These are the results we want to achieve. Value, Impact, a change in user Behavior, ROI. This is what actually matters.

This distinction represents the next logical step in the evolution of Agile thinking. In the original Agile Manifesto, the authors prioritized "working software over comprehensive documentation." That was a huge step forward twenty years ago, but it's not enough anymore. Today, we need to champion "validated learning over working software."

"Classic" product teams are measured by outputs, which inevitably leads to bloated, low-impact software. Effective teams, on the other hand, focus on maximizing outcomes. Their goal isn't just working software; it's "validated learning." The core principle that drives every decision is simple: "Maximize Outcomes, Minimizing Outputs."

5. Design your systems to enable learning.

If our goal is to validate ideas and learn as quickly as possible, then our technical architecture and practices must be optimized for that goal. Building a high-impact product isn't just about culture; it's about having the technical foundation to support it.

Here are a few key practices that facilitate product discovery:

  • Decouple release from deployment: Releasing a feature to users is a business decision. Deploying code is a technical one. They should not be the same thing. "Feature flags" are the essential tool that separates these two concerns, allowing you to test code in production safely. They are also the foundation for running experiments like A/B testing.
  • Don't fly blind: You can't learn if you can't see. Your system must have robust product instrumentation, metrics, domain events, and operational data. This feedback is essential for understanding user behavior and measuring the impact of your experiments.
  • Create a safe system to learn: Learning requires experimentation, and experimentation requires safety. Your system needs to have a low cost of failure. This is achieved through techniques like canary deployments, a solid experimentation framework, and a blameless culture that encourages trying new things.
  • Enable rapid prototyping: You should be able to validate hypotheses without writing a lot of production-ready code. An extensible architecture with APIs and integrations for nocode solutions empowers the entire team. A product manager or designer with access to open APIs can run dozens of experiments and achieve validated learning without ever needing to change the core production solution.

6. AI changes the game, but not the way you might think.

It's unclear exactly how AI will reshape software development, but one thing is certain: we can now generate code and features faster than ever before. AI coding assistants can produce working software in minutes that might have taken days before.

This sounds like pure upside, but here's the trap: if we simply use AI to build more software faster, we'll only accelerate the vicious cycle. We'll accumulate Basal Cost at an unprecedented rate, drowning our teams in complexity even faster than before.

The real opportunity with AI isn't to build more. It's to learn faster and be more ruthless about what we keep.

AI should enable us to:

  • Run more experiments and validate ideas quickly, iterating solutions before committing to production code.
  • Build prototypes to test hypotheses without the traditional cost of development.
  • Adjust and refine solutions rapidly based on real user feedback.

But this only works if we're radically more aggressive about:

  • Eliminating what doesn't work: If an AI-generated feature doesn't deliver impact, kill it immediately. The lower cost of creation doesn't justify keeping failures around.
  • Controlling complexity: Just because we can build something quickly doesn't mean we should. Every line of code still carries its Basal Cost.

The bottleneck has shifted. It's no longer about how fast we can build. It's about how quickly we can decide what to build and how fast we can learn from what we've built. Teams that master validated learning and ruthless prioritization will thrive. Teams that just use AI to build faster will simply create waste at machine speed.

Conclusion

To break the cycle of building software nobody uses, we have to fundamentally change our approach. We must accept that our job is not just to write code, but to solve problems and deliver value. This requires embracing a new set of principles.

First, recognize that software is a liability to minimize. Second, understand that empowered engineers are the best single source for innovation and product discovery. And finally, ensure that our technical solutions should optimize learning and discovery. By building our teams, culture, and systems around these ideas, we can stop wasting our effort and start building products that truly make an impact.

What is one thing your team could change tomorrow to optimize for learning instead of just delivery?



References

  • The Four Big Risks Marty Cagan (2017), Silicon Valley Product Group
    svpg.com/four-big-risks
  • The Most Important Thing Marty Cagan (2020), Silicon Valley Product Group
    svpg.com/the-most-important-thing
  • Software has diseconomies of scale – not economies of scale Allan Kelly (2015, revised 2024)
    allankelly.net/archives/472
  • Online Experimentation at Microsoft Kohavi, Crook, Longbotham et al. (2009), KDD 2009
    microsoft.com/research
    Documents that only ~1/3 of ideas improve metrics at Microsoft; Amazon's success rate is below 50%.
  • Are 64% of Features Really Rarely or Never Used? Mike Cohn (2015), Mountain Goat Software
    mountaingoatsoftware.com
    Analysis of the Standish Group statistic on feature usage.
  • Extreme Programming Explained: Embrace Change Kent Beck (1999, 2nd Ed. 2004), Addison-Wesley
  • Empowered Product Teams Marty Cagan (2017), Silicon Valley Product Group
    svpg.com/empowered-product-teams
  • Basal Cost of Software Eduardo Ferro (2021)
    eferro.net/basal-cost-of-software

Monday, December 22, 2025

Good talks/podcasts (Dec II)

These are the best podcasts/talks I've seen/listened to recently:
  • You ONLY Get Code LIKE THIS With TDD 🔗 talk notes (Dave Farley) [Continuous Delivery, Software Design, tdd] [Duration: 00:16] This talk explores Software Design as the core of development, illustrating how test-driven development (TDD) serves as a critical design tool for achieving modularity, cohesion, and continuous structural improvement.
  • Building effective engineering teams; lessons from 10 years at Google | Addy Osmani 🔗 talk notes (Addy Osmani) [Agile, Continuous Delivery, Engineering Culture] [Duration: 00:31] An exploration of how Engineering Culture integrates Technical Leadership, Management, and Developer Productivity to optimize Teams through Agile and DevOps practices.
  • Rethinking growing engineers in the age of AI | Meri Williams | LDX3 London 2025 🔗 talk notes (Meri Williams) [AI, Engineering Career, Engineering Culture, Technical leadership] [Duration: 00:23] (⭐⭐⭐⭐⭐) Meri Williams explores the urgent need to rethink engineering growth in the age of AI, advocating for a shift from manual coding tasks toward early tech leadership, systems thinking, and a "healthy paranoia" that allows leaders to "surf" the waves of technological change rather than be overwhelmed by them.
  • The Biggest Problem With UI 🔗 talk notes (Dave Farley) [Continuous Delivery, Software Design, team topologies] [Duration: 00:15] This talk explains why UI/UX design should be treated as an integral software design choice rather than a static specification, advocating for development teams to own the UI to ensure the system accurately reflects the user's mental model.
  • Shaped by demand: The power of fluid teams | Daniel Terhorst-North | LDX3 London 2025 🔗 talk notes (Dan North) [Agile, Product Discovery, Teams] [Duration: 00:23] Daniel Terhorst-North presents demand-led planning as a framework for building fluid, autonomous teams that self-organize quarterly to balance delivery, discovery, and Kaizen based on real-time organizational demand.
  • Tidy First? A Daily Exercise in Empirical Design • Kent Beck • GOTO 2024 🔗 talk notes (Kent Beck) [Agile, Engineering Culture, Software Design, XP] [Duration: 00:57] Kent Beck explores software design as a socio-technical exercise in human relationships and economic optionality, offering a framework to balance feature delivery with a sustainable engineering culture rooted in Agile-XP principles
  • Rafa Gomez - Attacking tech Debt: A Marathon, Not a Sprint - SCBCN 25 🔗 talk notes (Rafa Gómez) [Architecture, Product, Technical leadership] [Duration: 00:41] Learn how the "Marathon" approach enables engineers to tackle technical debt by adopting a product mindset that aligns long-term technical health with business value and consistent product delivery.
  • An Ultimate Guide To BDD 🔗 talk notes (Dave Farley) [Continuous Delivery, Software Design, tdd] [Duration: 00:18] Dave Farley explains how Behavior-Driven Development (BDD) utilizes executable specifications to improve software design and collaboration, facilitating excellence in Continuous Delivery through a user-centric, outside-in approach.
  • Unit Testing Is The BARE MINIMUM 🔗 talk notes (Dave Farley) [Continuous Delivery, Software Design, tdd] [Duration: 00:20] Learn how Test-Driven Development (TDD) serves as a critical act of design to achieve high-quality software by specifying behavior over implementation and enhancing modularity
Reminder: All of these talks are interesting, even just listening to them.

You can explore all my recommended talks and podcasts on the interactive picks site, where you can filter by topic, speaker, and rating: Related:

Saturday, December 20, 2025

Radical Detachment in the AI Era: Reinventing How We Build Software

Let me start with a disclaimer. I'm an enthusiast who loves trying new things, what some might call an early adopter, a geek, and perhaps a little bit obsessed. And right now, I'm enjoying this moment in our industry immensely, like a pig in mud.

A few months ago, something shifted. I had my "wow" moment, a realization that this changes everything.

For the last couple of years, as a Head of Engineering managing teams of 25 to 37 people, I had become one of those managers who "used to code." My chances of writing anything substantial were practically zero. In all of 2024, I made maybe 40 contributions to my personal repositories: a few commits here and there, mostly small fixes or experiments that went nowhere. The kind of sporadic activity you see from someone who loves coding but has accepted the inevitable trade-off of leadership.

Then, in early 2025, something happened. While still managing the same large team, with the same responsibilities and time constraints, I suddenly found myself shipping code at a pace I hadn't seen since I was an individual contributor. Over 800 contributions in just a few months. Not toy projects. Real, ambitious systems I'd kept on a mental backlog labeled "someday when I have time." The tools that made this possible? Primarily Cursor and Claude Code, with some experimentation with Codex along the way.

That's when it hit me: "This changes everything. Nothing will be the same again." We are now entering terra incognita, unknown territory. It's a time of total uncertainty, but it's also a time of unprecedented opportunity, which is what I want to explore with you.

To Build the Future, We Must First Invent It

"The best way to predict the future is to invent it." That was the philosophy of Alan Kay and his team at Xerox PARC in the 1960s and 70s. They didn't think about building products; they focused on inventing the future itself.

Their approach was grounded in a set of powerful principles. They thought about fundamental problems, not products, aiming to solve deep human or professional challenges. They identified exponential trends and created a 30-year vision. For them, it was Moore's Law, which they used to imagine what would be possible decades later. They explored with radical freedom in intensely interdisciplinary teams, mixing computer scientists with physicists, philosophers, and ethicists, believing groundbreaking ideas came from these intersections. They followed a "demonstrate or die" principle where ideas were nothing without practical, working prototypes. They built tools to build other tools, layering their inventions to create a platform for future innovation. And they always used systemic thinking, focusing on the whole rather than just optimizing individual parts.

A perfect example is the Dynabook. In 1968, they created a cardboard prototype of a portable personal computer. They knew the hardware didn't exist yet, but they trusted Moore's Law to make it a reality within 30 years. From this long-term, visionary thinking came some of the most foundational technologies of our time: Smalltalk, laser printers, Ethernet, graphical user interfaces (GUIs), and the personal computer. They also took object-orientation, evolved it, and carried it to its extreme. Steve Jobs later famously took inspiration from their work and brought many of these ideas to the masses.

A 30-Year Glimpse into Our AI-Powered Future

Following the Xerox PARC model, let's identify the current exponential trends in AI. The capability of LLMs is constantly increasing, with more parameters and larger context windows. The cost of inference is falling exponentially. And if the trends I'm observing hold, the speed of code generation could increase 10x every 3-4 years, though this is more intuition based on current trajectories than hard data.

These trends force us to ask some provocative questions about our profession. Will the strong distinction between "programmer" and "non-programmer" continue to exist? What will our role be when 99% of the code is written by AI? Will code quality still matter, or only "verifiable correctness"?

To avoid getting bogged down in the limitations of today's AI, let's project 30 years into the future.

What will seem ridiculous in 30 years? Not working with AI agents as integral team members, coding manually or "artisanally," and remaining at the same level of abstraction (that is, typing text into files).

What will still make sense? Solving problems using software, understanding and learning a domain, and contributing our knowledge to the business.

This leads to a powerful metaphor: in the future, manual coding will be like doing Sudoku or puzzles. It will be a stimulating mental exercise, a hobby for those who enjoy it, but not a professional necessity for building the vast majority of software.

Look, I know not everyone has had their "wow" moment yet. Your mileage with AI coding assistants might vary wildly from mine. Maybe you've tried them and found them frustrating, or maybe they just don't fit your workflow. That's completely valid.

But here's why I'm making this 30-year projection: I want to sidestep the debate about whether AI "works" for programming right now. That debate is too tied to individual experience and current limitations. What I care about is the trend, and the trend seems clear and irreversible. The investment, the adoption, the sheer momentum behind this technology doesn't look like a passing fad.

So whether you've had your moment of "this changes everything" or you're still skeptical, here's what we can't avoid: the change is already here. Organizations are already restructuring around it. Budgets are already shifting. Roles are already being redefined.

Which brings us to the critical question.

A Call to Action: Who Will Reinvent Our Profession?

The shift we are experiencing is not a minor innovation like blockchain or whatever the latest hype cycle is selling us. According to the models of economist Carlota Pérez (whose work on technological revolutions analyzes patterns across centuries of industrial transformation), this is a technological revolution on the scale of the steam engine or mass production. We are at a turning point that will redefine everything.

This brings us to the central question: Who do we want to reinvent our profession?

We have two options:

  • Option A: The consultants. Firms like McKinsey, whose articles on developer productivity reveal a fundamental misunderstanding of the nature of software.
  • Option B: Us. The community of practitioners who truly understand software's nature, people who have embraced Extreme Programming, Lean, and Software Craftsmanship.

This choice is being made right now. Not in five years. Not when "AI matures." Now. Every day that passes, more organizations are adopting AI productivity metrics designed by people who've never shipped production code. More engineering teams are being restructured by consultants who think code generation is just "faster typing." More junior developers are being evaluated by KPIs that measure activity instead of impact. The window to shape this transformation according to our values is closing.

The stakes are higher than a simple preference. This is a fight for the soul of software development. If we, the craftspeople, don't lead this transformation, the consultants will define the future of our work. And I am not going to like the profession they design for us.

But choosing Option B—choosing us—means more than just declaring we're in charge. It means accepting responsibility for each other. It means the experienced developers who mastered previous paradigms must guide those entering the field during its most chaotic moment. It means creating spaces where experimentation is safe, where failure is learning, and where knowledge flows freely instead of being hoarded. This isn't optional. If we don't take care of our community, we don't deserve to lead this transformation.

Revisiting Our Core Principles: Software is a Means, Not an End

The first line of the Agile Manifesto is key: "We are uncovering better ways of developing software..." It was never a static set of discovered truths. It has always been about continuous learning and adaptation. The prime directive has always been to satisfy the customer by solving their problems.

This brings us to the most important principle to remember today: Software is the medium, not the end. Our mission was never just to write code. It was to solve problems and create impact. If coding is destined to become a hobby like Sudoku, then our professional identity must be rooted in something deeper. The over-specialization that led to rigid roles like "frontend developer" or "DevOps engineer" was a mistake, a mistake that AI now gives us the power to correct.

Consider the software development "Food Chain", which maps the workflow from Opportunity Selection to Validating Impact.

This visual tells a crucial story. The top section, outlined in red and marked with a skull and crossbones, represents the "danger zone" of siloed, waterfall-style handoffs. This is where individuals are disconnected from the customer and the problem they are trying to solve. In contrast, the bottom section, outlined in green, is the "safe zone" where integrated, cross-functional teams own the entire value stream from beginning to end.

The implication is clear: AI makes it painfully obvious that roles isolated in the "build" phase are the most vulnerable. To remain relevant, we must move closer to the beginning (understanding the problem) and the end (validating the impact).

The Mindset of Radical Detachment

To navigate this new era, we need the intellectual humility to empty our own cups. We must unlearn what we think we know to make space for new ideas.

You Are Not Your Code

Because the nature of software is to change, we must practice radical detachment from our creations. Detach from your beautiful code, your elegant designs, and your favorite patterns. Holding on too tightly creates rigidity, turning what should be flexible clay into a brittle relic. Our business is not building finished solutions; it is evolving solutions over time.

The New Dynamics of Managing Complexity

With AI, the friction to generate new ideas, experiments, and complexity is almost zero. The process of software development will no longer be a slow, incremental growth of a single snowball. Instead, it will be a rapid cycle of expansion and contraction: exploring dozens of options in parallel, then radically deleting and simplifying to keep only what works. Managing this explosion of complexity will become one of the most critical skills we possess.

The Great Multiplier: AI in the Forest vs. the Desert

Beth Andres-Beck and Kent Beck describe two contrasting environments for building software: the desert and the forest.

The Desert is characterized by constant urgency, silos, poor testing, and misunderstood practices. It's a place of chaos and anxiety. The Forest is characterized by good practices, technical excellence that enables evolution, and close collaboration with the business. It's a place of sustainable growth.

AI is an indiscriminate multiplier. Its effect depends entirely on the environment it's applied to.

In the Desert, AI multiplies chaos. It becomes a factory for producing "fast trash," turning a technical debt problem into technical bankruptcy. In the Forest, AI multiplies discipline. It creates a virtuous cycle. Good practices like TDD, clean code, and good documentation provide the AI with better context, making it more effective. In turn, the AI makes it easier and faster to apply these good practices, turning them into unprecedented velocity and quality.

This leads to a paradigm shift. For the first time in our industry's history, the economic argument for software craftsmanship is no longer a nuanced discussion about long-term TCO. It is an immediate, undeniable, and exponential driver of value. AI makes excellence profitable in the short term.

Essential Practices for the AI-Augmented Developer

Certain engineering practices become supercharged in the AI era.

Modular architecture is essential. The rapid expansion-contraction cycle of development is only manageable within a modular architecture. Modularity provides the firewalls necessary to run dozens of parallel experiments without the entire system collapsing into chaos.

Clean code is crucial. Semantic, understandable code is essential for the AI to grasp business logic and provide meaningful assistance.

Quality and automated testing is non-negotiable. It is the only way to safely validate the massive volume of code AI can generate.

Small steps remain important. The principle of working in small, verifiable increments remains, but we must be open to the idea that the "size" of a step might change dramatically.

The Developer Laziness Scale

Think of your interaction with AI on a "laziness scale":

  • 100%: You write a prompt and blindly accept the output.
  • 80%: You glance over the code for obvious errors.
  • 50%: You review every line of AI-generated code carefully.
  • 20-30%: You code mostly by hand, using AI for autocompletion.
  • 0%: You write everything manually, artisanally.

The meta-skill is to treat this scale like a gear shift, consciously choosing the right level of automation and oversight for the road ahead. This requires retaining deep, low-level knowledge even when you aren't always using it directly.

FAAFO and Radical Simplification

The book Vibe Coding by Gene Kim and Steve Yegge introduces the FAAFO framework: a style of work that is Fast, Ambitious, Autonomous, Fun, and creates Optionality. AI is the engine that makes this possible, allowing us to tackle legacy refactors or build prototypes that once seemed impossible.

However, this power comes with a critical discipline. The ability to be Ambitious and create Optionality must be balanced with an equal commitment to radical simplification and deletion. This is where the discipline of radical detachment becomes a tactical necessity. We must detach from failed experiments as quickly as we create them.

Our Evolving Roles in the New Value Chain

AI is turning the "Build" and "Test" phases of software development into a commodity. The enduring human value, and therefore career security, lies at the extremes of the value chain: deeply understanding the "why" at the beginning and rigorously validating the impact at the end.

The bottleneck is shifting to the "fuzzy front end" (Opportunity Selection, Requirements Planning) and the "validated back end" (Running the system, Validating impact, and gathering Feedback). This highlights two critical skill areas for the future.

First, a product mindset. We need to deeply understand the problem, its context, and its intended impact. The challenge is no longer "is the code good?" but "does the system achieve the desired effect?"

Second, architectural and engineering practices. The responsibility for the system's results doesn't disappear; it intensifies. Skills in architecture, security, scalability, and performance become more critical because we will be making these decisions more frequently. AI can accelerate code generation, but the system will collapse without sound modularity and simplicity.

We Are All Beginners Again

Here's the uncomfortable truth: no matter how many years you have in this industry, we are all beginners in the Age of AI-augmented software delivery.

I've been doing this for about 30 years. That experience gives me some advantages: pattern recognition, intuition about what might work, the confidence to experiment without fear. But it doesn't exempt me from the uncertainty. When I'm pair-programming with Claude, I'm learning just as much as someone who started coding last year. The difference is that I have the luxury to be wrong, to throw away experiments, to admit I don't know.

But what about the people entering our field right now? They're walking into the most turbulent period our profession has ever seen, at a moment when the rules are being rewritten in real time. We, the experienced ones, have a responsibility to them that we cannot abdicate.

We must create safe spaces where they can learn without fear: on our teams, at local meetups, in conferences. We must share our experiments, even the failures. We must run hackathons where we figure this out together, just as we did with unit testing and Agile practices in the early 2000s. The difference is that now, the experienced among us must actively lower the barriers for those just starting, because the barriers are higher than they've ever been.

This is not charity. This is survival. If we hoard knowledge, if we gate-keep, if we let newcomers drown in the chaos, we will not have a community strong enough to fight for the soul of our profession. The consultants will win by default.

Our greatest strength has always been our community. Now is the time to prove it.

Your Path Forward: An Action Plan

So, what can you do right now to prepare?

  1. Move down the food chain. Get closer to the customer and the problem. Don't just ask "what"—always ask "why." Understand the business impact you are trying to create.
  2. Evolve from specialist to generalist. The era of the generalist is here. You don't need to be an expert in everything, but you need to learn enough about adjacent disciplines to be effective. AI can fill in the deep, specific details (like framework syntax), but you need to connect the concepts.
  3. Imagine our future tools. We should be building our own AI agents, encoded with our community's knowledge. Imagine a "gardener" agent that refactors code overnight, a "garbage truck" agent that identifies and removes dead code, or a performance-tuning agent that pinpoints bottlenecks. These tools are within our reach.

Conclusion: We Can't Avoid the Storm, So Let's Surf the Wave

We have the greatest opportunity in the history of our profession to finally build software in "the forest," a place where technical excellence and business impact are perfectly aligned. This requires adopting a product mindset and being willing to reinvent our best practices. It means letting go of what we think we know about software delivery, accepting that AI agents will become teammates whether we like it or not, and leaning heavily on our community as we navigate this together.

Of course, I don't have all the answers, and it's not all sunshine. There are serious issues that we, as a community, need to confront: the addictive reward cycle of working with AI, the consolidation of power in a few large tech companies, the challenge of training junior developers, and the environmental impact. These are important topics for future discussion.

But we can't let these challenges paralyze us. The change is coming. We can't avoid the storm, and honestly, we don't want to.

I've made my choice. I'm experimenting, sharing my failures as much as my wins, and making space for others to do the same. But I can't do this alone, and neither can you.

So here's what I'm asking: will we, as a community, step up and shape this transformation? Will we create the spaces where we can learn and experiment safely? Will we build the tools that encode our values instead of waiting for someone else to define them?

Or will we let this moment slip away while we debate whether AI is "good enough" yet?

The wave is here. The question isn't whether to surf it. The question is whether we'll surf it together, or watch from the shore while others ride it for us.


About This Article

This article is based on my keynote "Desapego Radical en la Era de la IA" (Radical Detachment in the AI Era), delivered at Software Crafters Barcelona in October 2025. The talk was given in Spanish and has been expanded and adapted for this written version. You can watch the original keynote and access the slides at eferro.net.

References

Saturday, December 13, 2025

Good talks/podcasts (Dec)

These are the best podcasts/talks I've seen/listened to recently:
  • This Mental Model Changed How I Design Software FOREVER 🔗 talk notes (Emily Bache) [AI, Agile, Architecture, Mental models, tdd] [Duration: 00:09] (⭐⭐⭐⭐⭐) Applying the mental model of Test-Driven Development (TDD) as an empirical engineering approach to master software design and manage complexity alongside Agentic AI tools.
  • From here to there and back again 🔗 talk notes (Simon Wardley) [AI, Strategy, Technology Strategy] [Duration: 00:57] Simon Wardley introduces maps for strategic situational awareness, detailing how technological evolution, inertia, and the rise of AI impact decision-making and software architecture, emphasizing the challenge of deciding where humans maintain control
  • Who Does What by How Much? Customer-Centric OKRs explained with Jeff Gothelf and Josh Seiden #ccokrs 🔗 talk notes (Jeff Gothelf, Josh Seiden) [Agile, Company Culture, Management, Strategy] [Duration: 01:14] (⭐⭐⭐⭐⭐) Experts Jeff Gothelf and Josh Seiden detail how to define customer-centric Objectives and Key Results (OKRs) by focusing on measurable outcomes, encapsulated in the framework’s core question: "Who Does What By How Much?"
  • Jim Womack on Lean Thinking: Past, Present & Future 🔗 talk notes (Jim Womack) [Company Culture, Lean Manufacturing, Management] [Duration: 00:32] (⭐⭐⭐⭐⭐) Jim Womack offers a comprehensive retrospective and prospective view of Lean thinking, exploring its evolution, current relevance, and future potential for a "second lean leap".
  • Vibe coding in prod | Code w/ Claude 🔗 talk notes (Erik Schluntz) [AI, Agile, Continuous Delivery] [Duration: 00:31] A discussion on how to safely practice "vibe coding" (letting AI generate code while forgetting the code exists) in production by acting as the AI's Product Manager and focusing on verification of leaf nodes and abstraction layers.
  • Analytics for not-so-big data with DuckDB 🔗 talk notes (David Ostrovsky) [Data Engineering, Performance] [Duration: 01:02] A deep dive into DuckDB, an embedded analytical database optimized for running high-performance analytical queries on "medium data" (1-100 GB range) locally on a single machine, with seamless integration for Python and diverse data sources
  • The New Code — Sean Grove, OpenAI 🔗 talk notes (Sean Grove) [AI, Agile, Architecture, Devops] [Duration: 00:21] OpenAI's Sean Grove introduces "The New Code," arguing that specifications are the universal artifact of intent, crucial for aligning both humans and advanced AI models.
Reminder: All of these talks are interesting, even just listening to them.

You can explore all my recommended talks and podcasts on the interactive picks site, where you can filter by topic, speaker, and rating: Feedback Welcome!
Your feedback and suggestions are highly appreciated to help improve the site and content. Feel free to contribute or share your thoughts!
Related:

Custom GPTs: New Permanent URLs

Quick heads up: my Custom GPTs have new URLs after switching ChatGPT accounts. These should be the permanent ones.

All four GPTs are now available at their updated locations:

The functionality remains the same — only the URLs have changed. If you've bookmarked the old links, please update them.

You can find all my projects, including these Custom GPTs, at eferro.github.io.

Saturday, November 29, 2025

Cursor Commands Added to augmentedcode-configuration

I've just updated my augmentedcode-configuration repository with Cursor commands that codify my XP/Lean development workflows.

What's new:

Added .cursor/commands/ with 8 reusable command patterns:

  • plt-code-review — Review pending changes (tests, maintainability, project rules)
  • plt-increase-coverage — Identify and test high-value untested paths
  • plt-plan-untested-code — Create strategic plans to close coverage gaps
  • plt-predict-problems — Predict production failure points proactively
  • plt-technical-debt — Catalog, classify, and prioritize technical debt
  • plt-mikado-method — Apply Mikado Method for safe incremental refactoring
  • plt-xp-simple-design-refactor — Refactor using XP Simple Design principles
  • plt-security-analysis — Pragmatic security risk assessment

Purpose:

These commands codify recurring workflows as reusable patterns. Instead of ad-hoc prompting, they provide consistent guidance for the AI to:

  • Work in small, safe steps
  • Focus on tests and maintainability
  • Apply Lean/XP principles
  • Follow project-specific conventions

They work alongside the existing base rules, creating a more complete configuration for AI-augmented development.

👉 Check them out: .cursor/commands/

This is an update to my original post: My Base Setup for Augmented Coding with AI

Perverse Incentives, Predictable Results: When Your System Sabotages Your Teams

It's a strange paradox. It took the manufacturing industry 50 years to move past the ideas of Frederick Winslow Taylor, known as Taylorism or Scientific Management. Yet in software development, a creative, knowledge-based discipline where these ideas are least effective, we continue to apply them universally.

Taylorism in a software context is the practice of maximizing the local utilization of each individual. We treat people like resources in a factory, keeping them 100% busy with their specialized tasks. This creates a cascade of perverse incentives that actively undermine collaboration, destroy flow, and cripple the efficiency of the entire system.

This article explores the three most common traps this thinking creates and offers a practical, systemic path toward improvement.

1. The Trap of Resource Efficiency

The Core Fallacy

Most organizations are obsessed with individual performance and 100% resource utilization. The goal is to keep every person busy all the time, believing this equates to maximum productivity. However, basic queueing theory teaches us that running any system at full capacity only generates blockages, chronic bottlenecks, and massive wait times. As a wise colleague once said, "If we optimize locally, in most cases we make everything worse."

The Connection to Taylorism

This is a direct application of Taylorism: maximizing the utilization of each "human resource" locally. We decompose work, assign it to specialists, and measure them on their individual output, ignoring the devastating impact on the system as a whole.


The Consequences

When you incentivize local optimization, the negative results are entirely predictable.

  • Perverse local incentives: We reward metrics that are easy to measure but destructive to the whole. This includes rewarding a high number of commits, celebrating people for "being 100% busy," or lionizing "heroes" who constantly put out fires.
  • Predictable negative results: These incentives inevitably lead to chronic bottlenecks, constant rework (also known as "failure demand" because you're fixing things that failed the first time), and a toxic hero culture where knowledge is hoarded and collaboration is discouraged.

The Alternative: Flow Efficiency

The antidote to this trap is shifting our focus from resource efficiency to flow efficiency. The book This is Lean explains the difference well.

  • Resource Efficiency: This is a process where work is handed off between specialists in silos. To keep each specialist busy, a queue of work forms before each handoff. From the customer's perspective, this is incredibly inefficient, as their request spends most of its time waiting in a queue.
  • Flow Efficiency: This is a team-based approach where everyone collaborates to finish a single piece of work. There are no "my parts." The team owns the work from start to finish. This delivers value to the customer much faster and eliminates the immense waste and rework inherent in siloed handoffs.

2. The Trap of Disconnecting from "Why"

The "Feature Factory" Anti-Pattern

A common anti-pattern is the "feature factory," where teams operate like an assembly line. Someone defines requirements, others implement them, and no one on the team connects with the customer or the actual impact of the work. Success is measured by output, not outcome.

The Connection to Taylorism

This is another core tenet of Taylorism: the rigid separation of "thinkers" from "doers." It promotes the unquestioning execution of specifications, regardless of whether those specifications actually solve a real customer problem.

The Predictable Results

Building without a clear purpose has disastrous and wasteful consequences.

  • Irrelevant products: Features are built that nobody uses.
  • Wasted talent: People work hard on things that simply don't matter.
  • Unnecessary complexity: Technology is over-engineered without a connection to a real-world need, creating a massive maintenance burden.

Advocate for Empowered Teams

The alternative is an empowered product team that deeply understands the purpose of its work: what problem they are solving, for whom, and why. These teams don't just blindly follow specs; they adapt solutions to meet real user needs, achieving far greater impact and velocity with less effort.

The Evolution to a Product Team

The journey from a siloed, handoff-driven process to a true product team is an evolution. An effective model shows the team's boundary of collaboration expanding across the entire value stream. In a traditional Waterfall model, each step (Opportunity Selection, Design, Build, Test, Release, Run) is a separate silo. In an ideal Product Team, the entire team collaborates across the whole process, from identifying the opportunity to operating the solution and learning from its impact.

3. The Trap of Deferred Quality

The Core Myth

There's a false dilemma that pits quality against velocity. We're taught to believe there's a tradeoff: you can be "fast without quality" or "slow with quality." This is a foundational myth in our industry.

The Truth

The data is clear. As shown in years of research from the Accelerate/DORA reports, the highest-performing teams have both high quality and high speed. The truth is: Quality does not compete with velocity; it enables it. Of course, context matters. A one-shot script, an MVP, or a proof of concept have different quality constraints than a core product. But for any sustainable product development, building quality in from the start through practices like testing and fast feedback is the only path to sustainable speed. A low-quality approach leads to a progressive slowdown as technical debt and failures accumulate.

The Connection to Taylorism

This myth is a direct descendant of a Taylorist mindset. It treats productivity as a measure of immediate outputs, ignoring sustainability. Quality is seen as a separate, final inspection phase, rather than something built into the process from the beginning.

The Negative Cycle

This mindset creates a system that actively discourages quality.

  • Perverse Incentives: The system rewards behaviors that produce low quality. We celebrate heroes who fix crises (often of their own making), equate long hours on weekends with commitment, and reward improvised hacks that create future problems.
  • Predictable Results: The consequences are severe and unavoidable. Teams are trapped in a cycle of chronic firefighting. Technical debt grows relentlessly, and the organization suffers from a high rate of talent drain as good people flee the constant chaos.

4. The Path Forward: Systemic Improvement

As W. Edwards Deming taught, over 90% of an organization's performance is a result of the system, not the individuals within it. The responsibility of management is not to blame people but to change the system so that work can flow and people can grow.


Here are actionable strategies to start changing your system.

Lead by Example

As a manager, you must model the behaviors you want to see. If you want teams to write tests, you should write tests. If you want them to refactor, you refactor. Make the desired behaviors visible and celebrate them publicly. Your job is to improve the system, not to find culprits.

Embrace Blameless Postmortems

Analyze incidents and errors transparently with the sole purpose of finding and fixing systemic weaknesses. The goal is to learn and improve, not to assign blame. When the system allows a mistake to happen, the focus must be on strengthening the system.

Show Vulnerability to Build Safety

To create an environment of psychological safety where people feel comfortable highlighting problems, leaders must be the first to show vulnerability. I often share my own past mistakes like the time I took down the phone system for an entire town or made a critical DNS error. Sharing these stories openly shows that errors are a part of work and that the important thing is what we learn from them.

Hack Your Performance Reviews

Traditional performance reviews are often toxic, reinforcing the individualistic, Taylorist mindset. If you are required to use them, hack them. Sometimes you must reinterpret corporate-level mandates to create the right local incentives. Subordinate individual accomplishments to the person's contribution to the team's overall impact. Focus on how they helped the team succeed, not just what they did on their own.

Build End-to-End Ownership

Create cross-functional teams that own a problem from end to end. This often means fighting against the silo mentality. A strategy I've used is to have my team actively take on more work (like operations or QA tasks) to eliminate external dependencies. This gives the team full control, deepens their knowledge, and allows them to optimize for the entire value stream.

Redefine 'Done'

A task is not "done" when the code is committed. It's not "done" when it's deployed. Work is only truly "done" when its impact on the customer has been validated with real feedback. This reinforces a product mindset and focuses the team on outcomes, not just output.

Hire for Mindset

Prioritize mindset and attitude over a checklist of specific technical skills. You can teach someone a new programming language; it's much harder to teach them that quality is their responsibility.

  • Product Thinking: Ask product management questions in interviews, like "What products do you admire and why?" or "How would you measure the impact of this feature?" Invite product managers into engineering interviews to help assess this.
  • Collaboration: Assess real collaboration, not just talk. When possible, have candidates work with the team for a day (in a paid, respectful way) on a real problem.
  • Flexibility: Your career path must reward generalists who provide flexibility, not just specialists.

Master Your Workflow with Kanban

Many teams use Kanban boards, but few use them correctly as a pull system. The three most important rules are:

  1. Use WIP (Work In Progress) limits. This is the simplest and most powerful way to optimize flow.
  2. Read the board from right to left. During stand-ups, review the work, not the people. Start with what's closest to being "done" (validated impact) and work backward. The focus must always be on finishing work, not starting new work.
  3. Use slack to unblock. When WIP limits leave someone without an immediate task, they should not pull new work. Their job is to help colleagues with open tasks, unblocking work further down the chain.

Reducing Resistance by Turning Change Into Experiments

The status quo naturally resists change. To move forward, we need to build the capability to generate change continuously, not just through occasional big initiatives. Approaches inspired by Lean Change Management can help: make small, frequent adjustments, learn quickly, and evolve based on evidence rather than assumptions.

One powerful tactic is to present changes as experiments. Framing them this way reduces resistance, creates psychological safety, and encourages people to engage with curiosity rather than fear. Even when the goal is meaningful transformation, breaking it into small, testable steps makes progress far more sustainable.

Define clear success criteria and a limited timeframe. This lowers resistance and allows you to validate ideas with data. As Grace Hopper famously said, “It’s easier to ask for forgiveness than it is to get permission.”

Conclusion: A Better Way to Work

A bad system will always defeat a good person. The Taylorist principles so common in our industry create systems that are destined to fail, leading to wasted effort, frustrated teams, and mediocre results.

We are discovering better ways to work. Through this experience, we have learned to value:

  • Collaboration and shared responsibility over heroes and a culture of blame.
  • Global optimization over local efficiency and specialized silos.
  • Significant impact and results over occupation and "being busy."
  • Autonomy with purpose over rigid control and supervision.
  • Continuous learning and adaptation over predefined and static processes.

By focusing on changing the system instead of blaming the people, we can create environments where teams can truly thrive and deliver exceptional value.

Management frameworks and their impact on software development.

Further Reading and Resources


Saturday, November 22, 2025

Scaling Systems and Teams: Five Mental Models for Engineering Leaders

Introduction: It's Not Performance, It's Scalability

In engineering, we often chase performance, but the true challenge of growth lies in scalability. Wikipedia defines scalability as the capability of a system to handle a growing amount of work by adding resources to the system. This is fundamentally different from performance.

Performance measures the speed or latency of a single request—how fast one thing happens. Scalability measures the system's ability to handle an increasing volume of work—how well it maintains its effectiveness as the load grows.

Consider two algorithms. Algorithm 1 (blue line) has excellent initial performance, processing requests quickly under a light load. However, as the load increases, its throughput hits a hard ceiling. Algorithm 2 (red line) starts with lower performance but scales linearly. As the investment of resources or load increases, its throughput continues to rise steadily.

While Algorithm 1 is faster out of the gate, Algorithm 2 is far more scalable. It is the system you want for the long term. This article explores five mental models to help you understand and design for scalability in both your technical systems and your human teams.

The Ideal World: Linear Scalability

Linear scalability is the theoretical ideal. In this perfect world, throughput increases in direct, linear proportion to the resources you add.

  • In Systems: If one database node handles 100 operations per second, adding three more nodes would result in a system that perfectly handles 400 operations per second.
  • In Teams: If a two-person team has a certain capacity, adding two more people would instantly double the team's output.

However, true linear scalability is a myth: it's the stuff of bedtime stories. It assumes 100% efficiency and zero overhead from coordination or shared resources, a condition that never exists in the real world. This fiction provides a useful baseline, but to build effective systems, we must understand why it fails.

The First Bottleneck: Amdahl's Law and the Contention Factor

Amdahl's Law provides the first dose of reality. It introduces the contention factor (α), which represents the portion of a system or process that is inherently serial and cannot be parallelized. This is the part of the workload that creates a queue for a shared resource—the bottleneck.

As you add more resources (like CPUs or team members), the work gets done faster, but only up to a point. The serial, non-parallelizable portion eventually dominates, and the system's throughput levels off, approaching a hard limit or asymptote.

The key takeaway from Amdahl's Law is that the maximum theoretical speedup is limited by this serial portion, defined as 1/α.

  • If just 1% of a process is serial (α = 0.01), you can never make it more than 100x faster, no matter how many resources you throw at it.
  • If 5% is serial (α = 0.05), your maximum speedup is capped at 20x.

Examples of contention are everywhere:

  • In Teams:
    • If you have a specialized team for deployments and operations, you create a bottleneck for all the other teams.
    • Critical tasks like database migrations or specific pull request approvals that could only be done by one or two people created queues and immense pressure on those individuals. These knowledge silos are classic examples of contention.
  • In Systems:
    • A monolithic infrastructure where all processes must compete for the same limited pool of computing resources.
    • Heavy optimization processes where certain calculation steps are inherently sequential, limiting the benefits of adding more parallel workers.

The Hidden Tax: The Universal Scalability Law (USL) and the Coherence Factor

The Universal Scalability Law (USL) builds on Amdahl's Law by introducing a second, more insidious factor: the coherence factor (β). This represents the cost of coordination: the overhead required for parallel processes to communicate and maintain a consistent, shared view of the system. It's the time spent "getting on the same page."

The critical insight of USL is that after a certain point, adding more resources can actually make the system slower. The graph of throughput no longer just flattens out; it peaks and then begins to decline.

This happens because the coordination overhead grows quadratically. The number of potential communication pathways between N workers is N*(N-1). As you add more nodes or people, the cost of keeping everyone in sync explodes, eventually outweighing the benefit of the extra workers.

Examples of coherence costs include:

  • In Teams:
    • Very large teams where decision-making requires consensus from everyone, leading to endless meetings and slowing down progress.
    • High levels of dependencies between teams that force constant coordination and block work from being completed independently.
    • It's often said that to scale, we need to communicate better. This is true, but counter-intuitively, it often means communicating less. The goal isn't more meetings, but rather to establish shared context, clear principles, and a strong culture so that less ad-hoc communication is needed. This reduces the coherence penalty and allows teams to operate more autonomously.
  • In Systems:
    • The Nextail BI Subsystem provided a powerful lesson in avoiding coherence costs. To calculate a specific metric, two independent, parallel processes each needed the result of a shared computation. The surprising lesson was that it was more scalable to have each process perform the exact same calculation independently—duplicating work—than to incur the quadratic communication penalty required to coordinate and share the result.

The Peril of 100% Busy: Insights from Queueing Theory

Queueing Theory provides a model for understanding wait times and the impact of system utilization. Its core lesson is stark: as a system's utilization pushes past approximately 80%, the wait time for new tasks increases exponentially.

This behavior creates three distinct regimes of system health:

  1. Everything is okay: At low utilization, the system is responsive.
  2. Oh wait...: As utilization approaches the "knee" of the curve, delays become noticeable.
  3. F**k: At high utilization, the system collapses, and wait times approach infinity.

This degradation is made drastically worse by variability. The curve for high-variability systems (the blue line in the graph below) shows that wait times begin to explode at a much lower utilization threshold (e.g., 40-50%) compared to low-variability systems (the green line). A queue that handles a mix of very short tasks (2 minutes) and very long tasks (2 hours) will collapse much sooner. A 2-minute job stuck behind a 2-hour job creates an unacceptable experience.

Practical applications of this theory include:

  • In Teams: The anti-pattern of a centralized Operations Team that becomes a single, high-variability queue for all other development teams is a recipe for bottlenecks. A better model is to embed operations capabilities within each team, making them self-sufficient. Similarly, organizing teams end-to-end (e.g., by product feature) instead of by technology (front-end vs. back-end) creates self-sufficient units that don't need to queue up for another team to finish their work.
  • In Systems: Moving from a single job queue (monoqueue) to multiple, specialized queues is a common strategy. By separating long-running jobs from short, interactive ones, you reduce the variability within any single queue, ensuring that quick tasks aren't starved by resource-intensive ones.

To Go Faster, Slow Down: Little's Law

The final mental model, Little's Law, offers a simple but profound relationship between throughput, work-in-progress, and completion time. The formula is:

Lead Time = Work in Progress (WIP) / Throughput

  • Lead Time: The average time it takes for a task to be completed.
  • Work in Progress (WIP): The number of tasks being worked on simultaneously.
  • Throughput: The average rate at which tasks are completed.

The counter-intuitive implication is powerful: for a given team or system throughput, the only way to reduce the average time it takes to complete a task (Lead Time) is to reduce the number of tasks being worked on at the same time (WIP). To go faster, you must start less and finish more.

Practical applications of Little's Law include:

  • Teams/Processes:
  • Set explicit and low WIP limits to force teams to focus on finishing tasks before starting new ones.
  • Prioritize flow optimization (getting single items done quickly) over resource optimization (keeping everyone 100% busy).
  • Embrace practices like pair programming, which focuses the energy of two people on a single task. This is a direct application of flow optimization, designed to finish one piece of work much faster, thereby reducing the total WIP and shortening the overall lead time for features.
  • Build a self-service platform that empowers all teams to perform tasks like deployments or database migrations. This increases the entire organization's throughput without creating a centralized bottleneck team.

Conclusion: From Theory to Practice

These five mental models (Linear Scalability, Amdahl's Law, USL, Queueing Theory, and Little's Law) provide a powerful vocabulary for reasoning about growth. The goal isn't to memorize formulas, but to use these concepts to facilitate better conversations and design decisions.

A practical framework I find very useful for thinking about scalability is:

  • Design for 2x the current size or client load. This keeps the immediate solution robust.
  • Consider what 20x would require. Would the current architecture or technology still hold?
  • Brainstorm what 100x would mean. This exercise helps uncover fundamental limitations that may require a completely different approach in the future.

Ultimately, a core strategy for managing scale is to break down a large problem into smaller, independent subsystems. By doing so, you can keep each component operating in the "happy," efficient part of its scalability curve. This is a strategic trade-off: solving a scaling problem at one level intentionally creates a new, higher-level problem of coherence between those subsystems. But this is the fundamental and proven pattern for building systems and organizations that can gracefully handle growth.


Sunday, November 09, 2025

Pseudo TDD with AI

Exploring Test-Driven Development with AI Agents

Over the past few months, I've been experimenting with a way to apply Test-Driven Development (TDD) by leveraging artificial intelligence agents. The goal has been to maintain the essence of the TDD process (test, code, refactor) while taking advantage of the speed and code generation capabilities that AI offers. I call this approach Pseudo TDD with AI.

How the Process Works

The AI agent follows a set of simple rules:

  1. Write a test first.
  2. Run the test and verify that it fails.
  3. Write the production code.
  4. Run the tests again to verify that everything passes.

I use the rules I defined in my base setup for augmented coding with AI. With these base rules, I can get both the Cursor agent and Claude Code to perform the TDD loop almost completely autonomously.

The refactoring part is not included automatically. Instead, I request it periodically as I observe how the design evolves. This manual control allows me to adjust the design without slowing down the overall pace of work.

Confidence Level and Limitations

The level of confidence I have in the code generated through this process is somewhat lower than that of TDD done manually by an experienced developer. There are several reasons for this:

  • Sometimes the agent doesn't follow all the instructions exactly and skips a step.
  • It occasionally generates fewer tests than I would consider necessary to ensure good confidence in the code.
  • It tends to generalize too early, creating production code solutions that cover more cases than have actually been tested.

Despite these issues, the process is very efficient and the results are usually satisfactory. However, it still doesn't match the confidence level of fully human-driven TDD.

Supporting Tools

To compensate for these differences and increase confidence in the code, I rely on tools like Mutation Testing. This technique has proven very useful for detecting parts of the code that weren't adequately covered by tests, helping me strengthen the reliability of the process.

Alternative Approaches Explored

In the early phases of experimentation, I tried a different approach: directing the TDD process myself within the chat with the AI, step by step. It was a very controlled flow:

"Now I want a test for this."
"Now make it pass."
"Now refactor."

This method made the process practically equivalent to traditional human TDD, as I had complete control over every detail. However, it turned out to be slower and didn't really leverage the AI's capabilities. In practice, it worked more as occasional help than as an autonomous process.

Next Steps

From the current state of this Pseudo TDD with AI, I see two possible paths forward:

  1. Adjust the rules and processes so the flow comes closer to human TDD while maintaining AI speed.
  2. Keep the current approach while observing and measuring how closely it actually approximates a traditional TDD process.

In any case, I'll continue exploring and sharing any progress or learnings that emerge from this experiment. The goal is to keep searching for that balance point between efficiency and confidence that collaboration between humans and AI agents can offer.

Related Content

My Base Setup for Augmented Coding with AI

Repository: eferro/augmentedcode-configuration

Over the last months I've been experimenting a lot with AI-augmented coding — using AI tools not as replacements for developers, but as collaborators that help us code faster, safer, and with more intention.

Most of the time I use Cursor IDE, and I complement it with command-line agents such as Claude Code, Codex CLI, or Gemini CLI.

To make all these environments consistent, I maintain a small open repository that serves as my base configuration for augmented coding setups:

👉 eferro/augmentedcode-configuration

Purpose

This repository contains the initial configuration I usually apply whenever I start a new project where AI will assist me in writing or refactoring code.

It ensures that both Cursor and CLI agents share the same base rules and principles — how to write code, how to take small steps, how to structure the workflow, etc.

In short: it's a simple but powerful way to keep my augmented coding workflow coherent across tools and projects.

Repository structure

augmentedcode-configuration/
├── .agents/
│   └── rules/
│       ├── base.md
│       └── ai-feedback-learning-loop.md
├── .cursor/
│   └── rules/
│       └── use-base-rules.mdc
├── AGENTS.md
├── CLAUDE.md
├── GEMINI.md
├── codex.md
└── LICENSE


.agents/rules/base.md

This is the core file — it defines the base rules I use when coding with AI.

These rules describe how I want the agent to behave:

  • Always work in small, safe steps
  • Follow a pseudo-TDD style (generate a test, make it fail, then implement)
  • Keep code clean and focused
  • Prefer clarity and maintainability over cleverness
  • Avoid generating huge chunks of code in one go

At the moment, these rules are slightly tuned for Python, since that's the language I use most often. When I start a new project in another language, I simply review and adapt this file.

🔗 View .agents/rules/base.md


.agents/rules/ai-feedback-learning-loop.md

This file defines a small feedback and learning loop that helps me improve the rule system over time.

It contains guidance for the AI on how to analyze the latest session, extract insights, and propose updates to the base rules.

In practice, I often tell the agent to "apply the ai-feedback-learning-loop.md" to distill the learnings from the working session, so it can generate suggestions or even draft changes to the rules based on what we learned together.

🔗 View .agents/rules/ai-feedback-learning-loop.md


.cursor/rules/use-base-rules.mdc

This small file tells Cursor IDE to use the same base rules defined above.

That way, Cursor doesn't have a separate or divergent configuration — it just inherits from .agents/rules/base.md.

🔗 View .cursor/rules/use-base-rules.mdc


AGENTS.md, CLAUDE.md, GEMINI.md, codex.md

Each of these files is simply a link (or reference) to the same base rules file.

This trick allows all my CLI agentsClaude Code, Codex, Gemini CLI, etc. — to automatically use the exact same configuration.

So regardless of whether I'm coding inside Cursor or launching commands in the terminal, all my AI tools follow the same guiding principles.

🔗 AGENTS.md
🔗 CLAUDE.md
🔗 GEMINI.md
🔗 codex.md


How I use it

Whenever I start a new project that will involve AI assistance:

  1. Clone or copy this configuration repository.
  2. Ensure that .agents/rules/base.md fits the project's language (I tweak it if I'm not working in Python).
  3. Connect Cursor IDE — it will automatically load the rules from .cursor/rules/use-base-rules.mdc.
  4. When using Claude Code, Codex, or Gemini CLI, they all read the same base rules through their respective .md links.
  5. During or after a session, I often run the AI Feedback Learning Loop by asking the agent to apply the ai-feedback-learning-loop.md so it can suggest improvements to the rules based on what we've learned.
  6. Start coding interactively: I ask the AI to propose small, incremental changes, tests first when possible, and to verify correctness step by step.

This results in a workflow that feels very close to TDD, but much faster. I like to call it pseudo-TDD.

It's not about strict process purity; it's about keeping fast feedback loops, learning continuously, and making intentional progress.

Why this matters

When working with multiple AI agents, it's surprisingly easy to drift into inconsistency — different styles, different assumptions, different "personalities."

By having one shared configuration:

  • All tools follow the same Lean/XP-style principles.
  • The workflow remains consistent across environments.
  • I can evolve the base rules once and have every agent benefit from it.
  • It encourages me (and the agents) to think in small steps, test early, and refactor often.
  • The feedback learning loop helps evolve the rule system organically through practice.

It's a small setup, but it supports a big idea:

"Augmented coding works best when both human and AI share the same working agreements — and continuously improve them together."

Adapting it

If you want to use this configuration yourself:

  1. Fork or clone eferro/augmentedcode-configuration.
  2. Adjust .agents/rules/base.md for your preferred language or conventions.
  3. Point your IDE or CLI agents to those files.
  4. Use .agents/rules/ai-feedback-learning-loop.md to help your agents reflect on sessions and evolve the rules.
  5. Experiment — see how it feels to work with a single, unified, and self-improving set of rules across AI tools.

Next steps

In an upcoming post, I'll share more details about the pseudo-TDD workflow I've been refining with these agents — how it works, what kinds of tests are generated, and how it compares to traditional TDD.

For now, this repository is just a small foundation — but it's been incredibly useful for keeping all my AI coding environments consistent, adaptive, and fast.

Related Content