QR codes, Macs, LLMs, and single-file, standalone CLI

The Mac does not have a tool for reading the data encoded in QR codes. Unlike the iPhone, you can't show the QR code to the camera and have it take you to the encoded URL. There are apps in the App Store that do this, but I don't really want to install an application for this infrequent need.

The solution was simply to ask an LLM to write a Python command-line interface!

Write a python script run with uv that will use the macos camera to take a picture of a QR code and then show the associated data encoded in the QR code.

A second later I have qr_scanner.py.

I have been using this technique often, especially with Claude Code. When the data needed is deterministic and frequently used I prefer to create a CLI and then direct Claude Code to use it. Generally this leads to fewer tokens, round trips, and quicker results. I use Python for these because a script + uv makes these tools single-file, standalone CLIs.

(And before you ask, yes, it took far longer to write this post than to create, use, and discard the script.)

AI technical debt

A recent client engagement was tough. The client had to meet stringent external deadlines for a product that needed a lot of custom code. Worse, the requirements -- business rules, input and output formats, reporting, etc. -- were scattered across many Word and PDF documents, Excel workbooks, and data schemas. In short, it was far too much for the small team to manually attend to and build upon.

The date was October 2025, and the answer then was to build a workflow using LangChain to combine multiple LLM prompts, CLIs, and input, output, and code exemplars. The guiding principle was to use the workflow to progressively improve the results. Don't manually improve the generated code; instead, refine the workflow and regenerate everything. Ie, update the prompts, change models, tighten the CLIs, improve the exemplars, reduce token use, and batch to speed generation.

It worked, until the engagement changed. New deadlines forced manual intervention with the code. Time and effort placed there took away from refining the workflow. Then more people were added to the team. The generated code became a legacy codebase to modify rather than to regenerate. Client senior management then effectively mandated vibe coding: "I don't care about quality, only features." Then a client's senior developer introduced a Claude Code skill that imitated the workflow's results but learned nothing from the experience of the original team.

The codebase is now a mess. Many "eras" of changing coding practices that we typically see in legacy codebases have now arrived in months instead of years. Updating the code has become progressively more difficult. Vibe coding, which once brought speed, is now needed just to deal with complexity. Deadlines were met, features were released, and no one believes the product is maintainable. §

The software development world has changed substantially since October 2025. This experience is likely just an example of us learning how to use these new tools better. I'm thinking that in our industry's timeline, the 2025–2026 period will be the strata equivalent of when the asteroid hit and killed off the dinosaurs. A black smudge.

(I must note that the original workflow was designed and implemented by two brilliant colleagues.)

Update: I titled this posting with "technical debt", but I think the cost here is different than those I outlined in Maintenance, evolution, and technical debt are different.

Kiro's "Frontier engineering" post

I do like Kiro's Frontier engineering post. I recommend that you replace "agent" with "subordinate" and then reread. If your organization is not already proficient at these 10 principles then it has much to catch up on. It can be done, I've both seen it and helped it. The good news is that LLMs can accelerate the improvements and fill the hard-knowledge gaps.

Getting MVP candidates in front of users is a Formula 1 race

Getting MVP candidates in front of users is a Formula 1 race. The race is not against competitors. It is a race against budgets of time and money, and prospective customers' attention. It makes little sense today not to use LLMs to gain speed. However, the speed of coding has never been the bottleneck after that point. The product engineering and management processes that we have used for decades to establish reliable and capable products continue to be important. LLMs do aid these processes. (Claude's basic /code-review and Matt Pocock's /grill-me, eg, have revitalized development.) In the end, it is people being tasked with giving a long-term future to your products and their users. That needs endurance to carry you far beyond the finish line.

The Software Architect Elevator: Redefining the Architect's Role in the Digital Enterprise

Gregor Hohpe's book The Software Architect Elevator: Redefining the Architect's Role in the Digital Enterprise is not what I expected it to be. I was lead to this book after listening to an interview with him on Beyond Coding. This book is about being an enterprise architect and not a systems architect. It does contain much good advice for the systems architect, but the enterprise architect is a far different role. This role is deeply technical and equally C-level managerial. Hohpe uses the elevator metaphor to emphasize the need to travel up and down between the enterprise's managerial and technical floors. The topics covered range from communicating effectively to organizational transformation. All treatments, however, are about technology in support of the enterprise.

The book is useful to any principle engineer, staff engineer, or systems architect looking for clarity as to their place and professional advancement in companies larger than their current employer.

I do now wonder how this role differs from a CTO. The purity of the CTO roles does seem to depend on the size of the enterprise. This LinkedIn discussion is useful.

Maddy Zhang's "Everything I learned at Microsoft in 9 Minutes"

I was not expecting Maddy Zhang's "Everything I learned at Microsoft in 9 Minutes" to have practical value. Especially with the sad faced, "Be Dumb..." thumbnail. I was wrong. It is awesome. She outlines 7 points that separate being a useful software developer and being a skilled software engineer. Watch the video.

  1. "Learn-it-all" beats "Know it all".
  2. Design for someone you will never meet.
  3. Backwards compatibility is important.
  4. Focus on security.
  5. Ship, then learn from users.
  6. Design constructive criticism.
  7. Who survives the AI area.

Update: Her video Agentic AI System Design was HARD until I Learned these 6 Concepts is also very good.