November 2025 Blog Roundup

I decided to try to blog every day in November in a tribute to NaNoWriMo. One trick I learned from Art and Fear, was to try not to have ideas for a blog post, but instead, have ideas for a series of posts. So, in the beginning of the month, I started with a ten-part series covering my new dev stack.

It starts with: Changing my Dev Stack (2025), Part I: Simplify, Simplify, and continues on to discuss Linux, Django, HTMX, VSCode and Copilot, Bulma, Sqlite, uv, other tooling, and networking. I also documented how my setup and philosophy helps me be more resistant to supply chain attacks.

I wrote about how I interleave reading, what I am currently reading, and what’s in my antilibrary (books I own, but have yet to read).

The rest of the posts were drawn from my current work. I wrote more about HTMX. I wrote about how fuzzy logic inference might be a better fit than LLMs for my project.

I’m not sure that I will keep doing this in December, but I do think I will write more here.

Protecting Myself

I was recently on the Scrum Master Toolbox podcast with Vasco Duarte in a series about AI assisted coding. In it, I said that I read every line of AI generated code (and fix it, if necessary) before I commit it.

This isn’t exactly right.

I read all code, even my own, and fix it before I commit. Doing it for AI is just an extension of how I normally work. I do this for my code because I often find problems. This is even more true for AI generated code.

Another reason to do this is because it makes code go through code review and testing faster. I have written about that previously:

Now that I am the only programmer on my project, I don’t need to worry about code review, but I do have to worry about DevOps, and frankly, I am not willing to trust AI to write code that I have to run. I have already fixed code that introduced beginner level security problems, so pure Vibe Coding on a project meant to be used by others on the web is not an option for me.

Dependency Maintenance vs. Supply Chain Attacks

I am assuming that you basically know what a supply chain attack is, but briefly, it’s when the code you install as a dependency in your development project contains malware. Unfortunately, all dependencies are code, and this code is usually run at a high privilege without needing to be signed.

The main thing it will try to do is grab keys and secrets from your .env files or environment variables and exfiltrate them. Some are targeted at blockchain developers and will try to steal their coins.

This is not a comprehensive guide. I am documenting my decisions based on my needs.

Like William Woodruff, I agree that We Should All Be Using Dependency Cooldowns. TL;DR is in the title. Essentially, never install a dependency that isn’t at least a few days old. The downside is defense against 0-day security fixes. If this is an issue, you could take the time to investigate and adopt the fix with an override.

The other broad advice with little downside is to not allow install scripts to run. You might still install malware, but if you let the install scripts run, they own you immediately. But since you are likely about to run the code inside your project, it’s not much protection. I do it anyway. The downside is when a dependency needs its post-install script to work. I used can-i-ignore-scripts to check for this issue when I used npm.

Ultimately, though, I have decided to leave the npm ecosystem and stop using node and React. Other ecosystems can have supply chain problems, but npm is having them on a regular basis because they are a prime target, and their practices have not scaled enough to deal with this.

I have also left Cursor and gone back to VSCode because Cursor’s fork cannot install the latest version of VSCode extensions. Extensions are also part of the supply chain and can be either malware or a hacking vector, so not being able to update them is not an option for me.

My next decision was to build a dedicated machine for software development. This machine does not have my personal data or information on it. It is not logged into any personal service (like my email). I have not yet dockerized all of my dev environments on it, but that’s a likely next step.

I also limit my dependencies. Another benefit of leaving the JS ecosystem is that Python isn’t as reliant on so many tiny dependencies. I was shocked at how many dependencies React, TypeScript and node/Express installed (I counted 10s of thousands of files in node_modules), and this is before you have written one line of application code. I like the batteries-included ethos of Django and Python. Most of what I need is built-in.

I have written a lot about dependencies and how it’s tech debt the moment you install it.

My final defense against supply chain problems is to have a regular dependency updating policy. Of course, this needs to be done with a cooldown, but my main reason to do it is because ignoring dependencies makes it very hard to do something about problems in the future. The more out of date you are, the harder everything is. Regular updating will also remind you of how bad it is to have dependencies.

To make this palatable, I timebox it. It really should take less than an hour for my project. Even at Trello, it only took a few hours to update the iOS project, which we did every three weeks. You also need extensive, automated test suites and time to test manually.

If updating takes longer for some reason, then the dependency that is causing this is now suspect. I will probably plan to remove it. If I need it (like Django), then I consider this a dry-run for a project I need to plan.

Thankful for Randomness

This Thanksgiving, I’m thinking about the random events in my childhood and teen years that led to my career as a software developer.

In middle school, I was lucky to have teachers like Mr. Abbey and Mr. Penner who got me into my first programming class, and Mrs. Cohen, who taught me to type.

My mom, who got me my first computer at Radio Shack.

My Aunt Grace, who got me a summer job in her office where a random programmer there took me aside and taught me SQL and where they had me make all of the spreadsheets in Lotus.

To the random guy at Barnes and Noble, who saw me in the programming book area and hired me to help him with a program he needed for his business.

Very thankful to the Randomness, the Great Creator.

My Current (late 2025) Interleaved Reading List

Yesterday, I wrote about Interleaved Reading (reading multiple books at once) and how it gives me a chance to reflect and retain a book’s contents. I try to pick very different books so that I have one to pick back up to match my energy.

I started Hypermedia Systems [affiliate] to give me a foundation on HTMX for a new project. A couple of chapters in, I decided to just try it. Now that I have something working, I went back to read the more advanced chapters. I like learning new tech this way rather than just reading because the building reinforces what I read. I also don’t want to just build because books like this are also about mindset, architectural patterns, and theory. Now that I have something working, I’ll just read the book through and should be done soon.

Earlier this year, I went to Germany and I wanted to be able to speak a little German while I was there. I had three months, so I crammed with DuoLingo and picked up Fluent Forever [affiliate] (here’s my review of it and the Fluent Forever app). There was no way I could implement that whole book in three months, but it did really help.

When I got back from my trip, I decided to switch to Spanish. I’ve been doing that for about six months and I’m ready to resume the book for more tips. This is a book I am reading just enough to implement the technique and then putting down. It might take months to finish.

I decided to pick up The Inferno [affiliate] by Dante (Cialdi translation) because I heard that there were references to it in Severance. I technically started it by reading the front matter and the first chapter (Canto), but I haven’t been able to get it into my routine. I have a small trip soon with flights back and forth. I should be able to finish it then.

I got Thinking in Systems [affliliate] by Donella Meadows as research for Swimming in Tech Debt, but stuck to the chapters on feedback loops (which is why I was reading it). It was hard to put it down, but I had to, and now I’m finishing it.

Even though some books take a while to finish, I sometimes find a book that I just want to read and finish immediately. Mostly this is because there is some information in the book I need. For example, when I went to LA recently, I bought and read Radically Simple Strength [affiliate] by Paul Horn after hearing him on a podcast. I have been wanting to lift weights more seriously, but I always overdo it and then stop. Horn’s method sounded like what I needed, and I finished it on the flight. It’s been working so far.

Before I interleaved books, I might have not bought a new book or waited until I was finished with my current one. Now, it’s more natural for me to be juggling a few for different time periods, so I can always put them all down if I just want to finish one.

I don’t know why it took me so long to interleave my reading. I consume other media this way naturally (e.g. TV series, podcasts, blogs, music). It might have made more sense when I needed to physically have the book on me, but they are mostly in Kindle now (and so on every device I own), so I have them all with me and can switch whenever I want.

If you don’t do this, it might sound confusing, but since I am usually working to retain the knowledge in between reading, it’s actually easy to pick the book up again.

Interleaved Reading

After graduating college, my book choices have been self-determined, and for a long time, I read them serially. This is weird because up until then I was always reading more than one book at time (by necessity).

But, a few years ago, while researching learning methods and incorporating spaced-repetition (i.e. flash cards) into my life, I saw a recommendation to interleave reading. The idea is simple: You read more than one book at a time. This might be obvious to some, but it wasn’t to me. It was liberating.

One problem of reading a book all the way through is that you don’t have time to consider a chapter before moving on. When you interleave books, you have time to ruminate on them in the background. Better than that, you can use spaced-repetition to build flash cards that you practice before moving on. Then, while you are reading, the older chapters are periodically shown to you, reinforcing the whole book as you read.

Another exercise is to write your own synthesis of the chapter, applying it to your personal interests. This kind of note can be a blog post or a page in your Digital Zettelkasten. Over time, these original thoughts might build up to something bigger. For me, it was my book.

Finally, I read a lot of books that are meant to be used, not just read. They offer their own exercises. For example, here’s a post about the way I use The Artist’s Way, a quintessentially useful book, which encourages you to read a chapter a week and then do some work.

Before I did this, retention was hard. Now, it’s effortless (a few minutes a day in Anki) or the effort is welcome (it generates a blog post). But, it does mean I put books down intentionally, and so I need a different one to read while I work on retaining the first one.

(I meant to write about what I’m currently reading today, but I thought it would be good to write about this first so I can reference it. I’ll get to my current reading list tomorrow)

My Antilibrary

I buy books as soon as I think I will read them (usually from a recommendation), but it might take time for me to get to them. I used to lament this, but then I read this take. In The Black Swan: The Impact of the Highly Improbable [affiliate], Nassim Nicholas Taleb writes:

You will accumulate more knowledge and more books as you grow older, and the growing number of unread books on the shelves will look at you menacingly. Indeed, the more you know, the larger the rows of unread books. Let us call this collection of unread books an antilibrary.

Here’s what’s menacing me now from my antilibrary and will probably read soon:

  • Write a Must-Read [affiliate] by AJ Harper: This was recommended in my writer’s accountability group as something to read before you write a book. It’s too late for that, but I have a general interest in the topic. I’ve only had this for a week.
  • Software Productivity [affiliate] by Harlan D. Mills. I found a reference to this book in a reread of Peopleware [affiliate] almost exactly a year ago. It’s out of print, but I found a cheap used copy and got it. It’s been on my desk almost since then.
  • Vibe Coding [affiliate] by Gene Kim and Steve Yegge. I got this when it went on presale a few months ago. I better read this soon, because it will age quickly.
  • The Real Play Revolution [affiliate] by Ash Perrin. Ash is a clown who travels worldwide to refugee camps to entertain children. I saw him speak at PINC in Sarasota two years ago and bought the book there (mostly to support his efforts). There’s another PINC coming in a few weeks (Dec 11-13), which I highly recommend if you are in the area.

I usually read multiple books at the same time, picking up the one I have energy for at any given time. I try to keep them different from each other, but they are usually all non-fiction. I’ll write about that tomorrow.

Moats and Fast Follow For Vibe Coded Projects

I wrote about how, at Atalasoft, I told my engineers to Be Happy When It’s Hard. Be Worried When It’s Easy. We competed against open-source and in-house solutions. When we found valuable problems that were hard to solve, I was relieved. The same is true for vibe coded solutions.

If you can create a valuable app in two weeks, then so could a competitor. If your secret sauce is your idea, then that’s hard to protect if you want people to use your app. We don’t even know if AI generated code is copyrightable, so it’s very unlikely to be patentable (i.e. inventors must be humans).

Here are three things you could do:

  1. Keep building on the idea – right now, someone following you has the benefit of seeing your solution and feeding that to the AI. So, it helps if you can keep building on the idea and hope they can’t keep up. If you do the minimum, the bar is too low.
  2. Build on secret data – once you have a working system, the biggest moat you have is the data inside the system. AI can’t see that or reproduce it from scratch. Build new (valuable) features that require secret data to work. This doesn’t need to be used as training data. This is like a network effect, but more direct and long-lasting.
  3. Use your unique advantages – If your app is a simple UI on CRUD operations, then it can be reproduced by anyone. But, let’s say, you have personal branding in a space. Can you make an app that extends on it? Do you have access to hard-to-win customers? A mailing list, subscribers, etc? Fast-followers might be able to recreate your software but your audience won’t care if they trust only you.

Of these, I am relying mostly on the last one. The software I am working on is an extension of Swimming in Tech Debt. It takes the spreadsheet that I share in Part 3 and builds on it with better visualizations than the built-in ones. Someone could clone this, I guess, but probably they would need to reference my book in order to explain it. I am indifferent to whose software they use if this is true.

It’s not Debt if You Don’t Care About the User

I recently read Are consumers just tech debt to Microsoft? by Birchtree, where they say:

Microsoft just does not feel like a consumer tech company at all anymore. Yes, they have always been much more corporate than the likes of Apple or Google, but it really shows in the last few years as they seem to only have energy for AI and web services. If you are not a customer who is a major business or a developer creating the next AI-powered app, Microsoft does not seem to care about you.

Their thesis is that Microsoft’s share of the consumer market will plummet because the consumer is tech debt to them. I think of the user as a facet of tech debt, not the debt itself.

In Swimming in Tech Debt, I present eight questions you should answer about tech debt. One of them, called “Regressions”, asks how likely it will be that you will break working code for users that you care about. The more you might, the more, I believe, that you should not touch this code (or be very careful with it).

But, if you don’t care about the users, or they don’t care about the features the indebted code provides, then it’s likely that you can just rewrite it with impunity. You can change it without risk. You might be able to delete it. If so, it’s hardly a debt.

If you do value a market and change code radically, the consequences can be fatal (see Sonos). But if you don’t, then doing the minimum is rational.

Workshop: Eight Questions to Ask About Your Tech Debt

In Part 3 of my book, Swimming in Tech Debt, I write about how teams should plan projects to address larger technical debt issues. The bulk of the chapters in the section explain how to manage a tech debt backlog.

Drawing on the practices of product managers and how they manage feature backlogs, I propose a scoring system to drive the discussion.

The scoring system breaks down the costs and benefits of paying debt (or not paying it) and gives you a way to compare items to each other. It starts with this diagram:

Diagram showing Pay and Stay Forces

The benefits of paying debt and the costs of not paying (staying) drive the Pay Force. Inversely, there are benefits to staying and costs to paying that indicate you should leave the debt alone. These eight dimensions are scored by answering a related question:

  1. Visibility: If this debt were paid, how visible would it be outside of engineering? 
  2. Misalignment: If this debt were paid, how much more would our code match our engineering values?
  3. Size: If we knew exactly what to do and there were no coding unknowns at all, how long would the tech debt fix take?
  4. Difficulty: What is the risk that work on the debt takes longer than represented in the Size score because we won’t know how to do it?
  5. Volatility: How likely is the code to need changes in the near future because of new planned features or high-priority bugs?
  6. Resistance: How hard is it to change this code if we don’t pay the debt?
  7. Regression: How bad would it be if we introduced new bugs in this code when we try to fix its tech debt?
  8. Uncertainty: How sure are we that our tech debt fix will deliver the developer productivity benefits we expect?

If you have bought my book and would like me to talk to your team about this process, get in touch. It would be a 45-minute presentation with 15 minutes for Q&A.

In the presentation, I score 3 backlog items from my career and then show how the scoring drives the decision making of what to do. I encourage you to record it and then go through the presentation with a couple of examples from your backlog.

This workshop is free. Write me on LinkedIn or through my contact page.

After taking the workshop, reach out if you would like me to facilitate your technical debt backlog planning sessions. The book has agendas, scoring guides, and a catalog of score-driven debt remediation ideas, but I’m happy to tailor them to your needs.