kirit.com

Writing about C++, Programming, the web, Thailand and anything else that catches my attention—with some photos thrown in

Congratulations on your promotion to Tech Lead

Posted 2026-08-22T04:57:19.818968944Z, last edited 2026-08-22T06:54:32.187070898Z

Last Thursday night I gave a talk at the local developer meetup. As part of the prep for that I wrote a script as if I was delivering it. This was something new I tried out as I wasn't sure if I'd be able to get speaker notes on my screen with the projector (which has been a problem in the past when I've tried to rely on them).

This is just the slides that I used and that pre-written script. Of course what I actually said was quite different. I think I went a bit short on some of the early slides, and a bit (sometimes much) longer on the later ones, but the jist of what I wanted to get across should be clear enough.


Title slide: 'Congratulations on your promotion to Tech Lead', subtitled 'What's next?'
  • (title)

Intro slide linking kirit.com and Mastodon @KayEss, beside a screenshot of the Blue Weave synth's hex-grid editor and its ADSR panel
  • Hi, my name is Kirit and I want to talk a bit about how we manage AI agents to do coding. (I’m also writing a synth, so if anybody wants to talk about audio synthesis and sound design come chat afterwards). I did my first paid software development way back in 1985, so I’ve been doing this for a while now and I’ve seen a few changes. What I want to talk about though are the things that haven’t really changed

'Confession time': who here uses AI agents for coding, who has shipped AI code without looking at it, and does that feel like a problem?
  • (ask questions)

'Confession time' continued, adding: who has led a development team, and who has shipped code they didn't read?
  • (ask questions)

Full-screen statement: 'Being responsible for code you've not read isn't a new thing'
  • Those of us who have led teams know that shipping code that we’ve not looked at isn’t a new thing – if you’ve led a team you’ve been doing this, and as an industry we’ve always done this. AI agents are accelerating our ability to write more code, so what do we have to do so we don’t feel guilty about our inability to read it all?

Section divider: 'What are agents doing?'
  • So what is it that the agents are doing? I want to draw some parallels about how agents go about their tasks and how another group of developers also go about it

'Not thinking things through' - what agents do: instead of finding things out, they jump to conclusions
  • One of the things that is very noticeable when dealing with an agent is that they have a very strong proclivity to action – they want to jump straight into a problem and start trying to code their way out of it.

'Not thinking things through' - the same 'jump to conclusions' trait shown for agents and junior developers side by side
  • The same happens with junior developers. They start to code the first thing that pops into their heads and run with it.

'Getting stuck' - agents and juniors both loop trying to fix a broken tool instead of the problem at hand
  • If the agent or the junior gets stuck with this first idea, they don’t back out and think again. They keep going, trying to fix it. You see the same when some tool they were planning on using doesn’t work, they get stuck trying to fix the tool instead of re-evaluate their approach

'Over-reliance on training' - agents let training overwhelm your instructions; juniors reach for whatever they last learned
  • The ideas that they do have tend to be only what they’ve seen before. Agents have a strong bias to repeat what’s in their training data, and juniors have a strong bias towards doing again whatever they did on their last task

'I'm done' - agents and juniors declare they're finished before checking their work; the junior's version is 'works on my machine'
  • Once they have something that appears to work they declare it done. They don’t think about their work critically, and they don’t try to “falsify” their solution – that is think about how it can be broken

Section divider: 'What's different?'
  • But agents aren’t exactly like junior developers

'Short attention spans' - an agent's context window fills up, so it forgets and gets stupid
  • Agents have technical limitations in their context window that we don’t see outside of small children (there’s a reason for school days being so short). Even the most junior of developers beat them out there

A giant '0%': the chance of an agent getting paged at 2am over a system outage
  • The agent is also never the one who gets woken up at 2AM when production falls over. It turns out that being “inconvenienced” by these situations is one of the things that teaches you to do better, and (just as importantly) to insist on better

Full-screen statement: 'AGENT.md != Experience'
  • You simply can’t get as much about the project you’re working, it’s why’s and how’s, into an agent.md file as you can hold in your own head. You can build a much stronger understanding of the project for yourself than you get across to the agent.

Blue section divider reading 'What's next?'
  • So what do we do? I’m going to focus on a single thing that helps not only when you’re managing a bunch of agents, but also when you’re managing a team of people.

'Fridge Logic', with links to the TV Tropes Fridge Logic and Fridge Horror pages, beside the anime double-take reaction meme
  • There’s a trope in story telling about what happens after the story is over. Fridge Logic and Horror are about conclusions you come to after you’ve finished watching the film, show or reading the book and you think about what you’ve experienced. Maybe there’s something truly terrible in there

'Dune' - is Paul Atreides the hero, the villain, or a tragic anti-hero? beside a film still of Paul holding a crysknife
  • In the Dune books (and films) we read Paul as a heroic figure overcoming his enemies and getting revenge. But is that the right reading? How does it change the more you think about it? Maybe you eventually come to the conclusion that Paul is no hero at all, for the people he leads he’s no more heroic than any other noble – just somebody else to follow who’ll likely get you killed. Maybe the real message is “beware of messiah figures”?
  • The very best stories are written not just to entertain in the moment, but to give us something to think about later. The very best give us something to think about years or decades later

Terry Pratchett quote from A Hat Full of Sky on First, Second and Third Thoughts - the rare Third Thoughts that 'watch the world and think all by themselves'
  • (read quote) What Terry Pratchett is talking about is a skill that you can (and should) learn. To spend time thinking and reflecting on what you’re doing, to understand it well enough that can think more deeply about what’s around you

'Cultivate your Third Thoughts' applied to a NULL bug: from 'add a null check' to 'why does this codebase keep handing us nullables at all?'
  • You see a bug to fix that a NULL value is getting through somewhere. Your first thought is to fix the bug, after all, that clears the ticket and gets you to the next task. Your second thoughts might be to trace down why the NULL appears and fix it there instead. Your third thoughts might be about why there’s a NULL there at all, is there anything you can do to reject this entire class of error?

'The agent doesn't live - you do': it only responds to input, doesn't exist between prompts, and reading intent into it is pareidolia
  • The biggest weakness that the agent has is that it is only able to respond to an input. It has no existence when it’s not answering or responding to a prompt. It’s up to you to ask the right questions and to do the deep understanding. So to ship code you’ve not read, you need to challenge the agent (or the person) in ways that they can’t or don’t think and to fill in those gaps – this is what we’ve always done when it was just humans in the mix, and it doesn’t change now there’s agents too. But don’t think of them as human.
  • Pareidolia is seeing faces in toast and in the same way, don’t confuse an LLM with anything actually human2.

Orange section divider reading 'What's next?'
  • Cultivate your third thoughts. Engage in understanding the systems you work on. Engage in understanding the business that surrounds those systems support and work within. The one piece of advice I keep circling back to when asked “how do I become better in this industry” is to be “interested” (not interesting!).

Closing answer to 'What's next?': 'Be interested & go manage your team!'
  • Listen and take notice of what’s going on around you and spend time thinking about it. Go manage your team!

Closing contact slide: kirit.com and Mastodon @KayEss, with Sally, the Blue5alamander mascot holding a game controller
  • (questions)

I think it went over quite well. The questions at the end showed that I had gotten my point over well enough, as they were relevant to what I was saying — which was really good.

When I had these notes open on my phone they were in a numbered list (and I had the slide numbers turned on) so I could easily and quickly find the note I needed for each slide if I needed to look and make sure I'd covered what I needed. To help orient myself I also put some words in bold. This turned out to be great because it led my eye to the important bits.

So what is it that the agents are doing? I want to draw some parallels about how agents go about their tasks and how another group of developers also go about it

In the past I've sometimes gotten lost reading the notes and wasn't able to find the reminder I needed at a glance.


Blue Weave

Posted 2026-08-02T08:13:48.895221951Z, last edited 2026-08-02T09:48:22.986903567Z

Over on the Blue 5alamander site we've announced Blue Weave, a synthesiser we're building. I've been working on parts of the synth for a couple of years off-and-on now, but for the past few weeks I've switched to full time on it.

A lot of the parts of the synth are already working, at least as far as audio output is concerned. But turning this into a product other people can use is going to require a lot of UI work to make a great UX. The additive sounds (with their accompanying subtractive parts and layering) work quite well and I've been using them to make new sound effects for Zeta 6 Survivors for the past few releases. The FM synth though needs a much more complex configuration that really needs to be viewed rather than read.

I think I'm nearly half way through everything I need to make an interesting first release of the FM synth, which is what will be in 0.1. I've spent very little time on actual audio output — it's all gone into UI work. That's good, I think — the UI has to be good — so I'm looking forwards to seeing how other people react to it when they try it out.


AI Assisted coding

Posted 2026-02-27T05:33:43.558Z, last edited 2026-08-22T06:23:31.480812203Z

I've been experimenting a bit with AI assisted coding. Due to a recommendation from a friend, I'm currently using Z.ai's GLM 4.7 and 5 models with Claude's CLI tooling.

And despite myself I quite like it.

I've been using chat interfaces to help with some things, especially debugging Vulkan code, for a while now and I've been finding it quite helpful — largely the LLMs seem to have a much better understanding of Vulkan than I do4.

In the part of some game code I'm working on at the moment, the player needs to make a choice of reward when they level up. This requires a new modal dialog which asks the player which of the proferred options they want to accept. I'd already done the code that worked out which options to offer, so I now needed the code that asked the player.

There's a good deal of set up in something like this, so I asked the AI to do it for me. I told it I wanted a new file for the level up modal and waited to see what it came up with. And it really surprised me by coming up with something structurally nearly identical to what I would have done. In order to do this it had to:

  • Work out how the signalling that the player had leveled up worked and where the choices appeared in the signal.
  • Work out how to interface a coroutine waiting on this signal needed to interface with the in-level signalling that a new modal was required.
  • Work out how to implement the new modal, including work out how the UI layout code I'd written in the game worked.
  • Work out how the drawing of the modal had to interface with the render loop so it would draw until the player made a choice.

Frankly I was sore amazed.

I had some quibbles: I didn't like some of the names it used, it forgot to add the new file to cmake, and it wired in the request for the modal to an existing coroutine that was showing notifications on level up. When asked it happily made a new coroutine for me and correctly worked out when and where to start it. I quickly fixed up the other things I didn't like.

Debugging

Today I was continuing with this work, and I noticed that the game was offering the same damage upgrade for both the bolt and tractor turrets, which didn't make sense. This sort of debugging can be either quick or slow as there's a lot of places that the error could be, so another perfect task for the AI?

And indeed it found the bug very quickly. The code looked like this:

void core::component::turret::improvements(
        gamedata::rarity::ref rarity,
        gamedata::projectile::improvement::pool &pool) const {
    auto const &pc = [&]() -> gamedata::projectile::ref {
        switch (weapon->configuration.projectile) {
        case gamedata::projectile::type::bolt:
            return gamedata::projectile::definition::named("bolt");
        case gamedata::projectile::type::tractor:
            return gamedata::projectile::definition::named("bolt");
        }
    }();
    for (auto const &i : pc.configuration.improvements.at(rarity)) {
        pool.push_back(i);
    }
}

Clearly I felt pretty foolish for having made such an obvious copy & paste error, but I find these sorts of bugs are often the hardest to find simply because they make so little sense5.

When I asked the AI for a fix it made the suggestion of simply fixing the typo, which of course I rejected:

● Update(src/core/components.cpp)
  ⎿  User rejected update to src/core/components.cpp
      290          case gamedata::projectile::type::bolt:
      291              return gamedata::projectile::definition::named("bolt");
      292          case gamedata::projectile::type::tractor:
      293 -            return gamedata::projectile::definition::named("bolt");
      293 +            return gamedata::projectile::definition::named("tractor");
      294          }
      295      }();
      296      for (auto const &i : pc.configuration.improvements.at(rarity)) {

I've spent most of the last thirty years mentoring colleagues on software development practice and craft, and this is exactly the sort of change I'd expect from a very junior developer. They will always go for the simple and obvious fix rather than take any wider considering into account — juniors, like LLMs, are not afraid of code volume — and if a change in one place requires also a change somewhere else, well, that's just the rules of the game. We have a label for this sort of code: technical debt.

I preferred a different way, and the function now looks like6:

void core::component::turret::improvements(
        gamedata::rarity::ref rarity,
        gamedata::projectile::improvement::pool &pool) const {
    auto const &pc = gamedata::projectile::definition::named(
            gamedata::projectile::to_string(weapon->configuration.projectile));
    for (auto const &i : pc.configuration.improvements.at(rarity)) {
        pool.push_back(i);
    }
}

The future?

Back when I started programming in 1980s we had to write in assembly if we wanted performance. These days nearly all of us write in higher level languages and let the compiler take care of the machine code for us. I've not written any assembly since the early 90s, and of course my productivity is better for it (even if, sometimes, maybe, I could do a better job than the compiler — but I'm betting not often). The truth is that for most code, for most of the time, it just doesn't matter enough.

Superficially the use of AI feels similar. I can see a future approaching rapidly where I'm willing to hand over more and more of a task to the AI assistant, but I'm not yet seeing that they won't need help.

Their willingness to throw ever more code at a problem until it's fixed is something that still needs to be fought against. All that we've learned in the craft of software creation is still relevant, even in this new age.

For the time being at least.

We are losing something though. When I write C++ and let the compiler turn into machine code, this is a deterministic process and the "prompt" (the original C++) is of course preserved. When prompting an AI all that is left is the code and whatever documentation we get the AI to write for us. This means that we're now dealing with an inherently lossy process, which wasn't the case before. How much is that going to matter? It's too early to tell really, but my expectation is that it's going to matter a lot, especially as the code volume goes up and the ability of humans to understand it goes down.

So many of the projects I've worked on have had the management of complexity as a central aspect of the problem domain. The issue was never about how much code we could deliver, the task was to work out what a tenable solution would look like so that complexity could be managed, and the solution was transparent enough that everybody could understand it. Then the code had to conform to that architecture so that it was still obviously correct.

The ability of AI to assist in our development is only increasing, but I still see a big role for developers with craft to manage the process lest we drown under a sea of technical debt.


Addendum

I wonder if there isn't a conflict of interest here for the companies selling us access to the coding models. The more code we have to maintain, the more we have to pay for token processing, the more we have to pay to upgrade to models with ever bigger context windows, the more GPUs and data centres are going to be needed. The more we drown in technical debt the more we have to pay them to try to surface. I'd feel a lot happier if our financial goals were a lot better aligned.

Do we have an ethical obligation to still look after our craft and make the code as good as it can be using our more traditional metrics? There's a clear feduciary responsibility there for the managers of the companies that are using AI assistance (I'm particularly thinking about non-tech companies that hire developers), but it may only become apparent after most of the software engineers are gone and only the AI companies are left.