Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • I feel like AI might let us model some of the things that we initially didn't scope that led to these problems (e.g. "Decided not to fix every bug, or upgrade every dependency") - being able to more easily ask a system that can dig into "how much time are we spending on stuff related to foo"

    AI tooling can also be a place where we start building our view of what maintainable software practices look like so we don't make decisions that have these same tail effort profiles. That can be things like building out tooling to handle maintenance updates

    I think the real thing that comes out of AI tooling is probably that the tooling needs to be trained (or steered) towards activities that enhance human attention management.

  • > AI tooling can also be a place where we start building our view of what maintainable software practices look like so we don't make decisions that have these same tail effort profiles. That can be things like building out tooling to handle maintenance updates

    This has been possible already but from my vantage point, it doesn't look like anyone really did it? Sure, there already exists tons of OSS that is built for this case, even before AI, yet it seems to me to always come back to incentives. IMO, there is no incentive to write maintainable software (and I'm not sure there ever will be one at this pace). Businesses are only incentivized to write enough software to accomplish the task within their own defined SLAs and nothing further. But even that doesn't seem to be a blocker at this point if Github is used as an example.

    Good software comes from people who care deeply about solving the problems in way that they are invested in. If your employees don't care about your product, you're already starting on the wrong foot. AI isn't going to incentivize bad-average developers to write better software or a good developer to push back harder against their clueless manager. When they make the decision, AI might help (assuming it doesn't make a bigger mess) but it's not going to reduce technical debt in any meaningful way without a sea change of perspective from product managers around the world.

    So far, I just don't see it happening in theory or in practice. I hope I'm proven wrong!

  • Yeah, but to be honest, I sometimes just tell Claude to cleanup / refactor stuff; it finds a lot of things, discusses it with me and I approve the plan, and it churns away my tokens for some time. I do this once in a while, and I've been doing this for over 6 months and I don't feel like my development has significantly slowed down. Yeah my token usage is more for sure, but my codebase also is, so I'm not worried about that. To me AI seems to make maintenance very easy, like the rest. You just need to do it.

    Edit: I make it sound a bit simple maybe. I do more extensive redactors also, where I'm more involved and opinionated. But I don't feel the need to do that very often very deeply. But yeah sometimes it's definitely necessary to prevent the project from going off rails.

  • I'm getting downvotes for this. Why exactly?
  • This is my experience exactly.

    I have reduced our response time on our api to 30ms from 80ms and gotten a setup we can comfortably grow into.

    I had not had time to track down these optimizations without Claude code.

  • Yeah, there's a double-standard I've been seeing in LLM discourse here: LLMs suck but they are also somehow expected to proactively do maintenance sweeps in your code over time and repay technical debt, presumably on your behalf.

    If you want to build well-architected, well-tested code or pay back debt, the LLMs make the world your oyster. And it's easier than ever since LLMs have no problem doing ridiculous cross-cutting refactoring that you'd never have done on your own.

    That LLMs essentially lead to code that's harder to maintain, or that human-produced code is easier to maintain by default just aren't claims I'd sign off on, and TFA doesn't try to render the argument.

    I'd argue the opposite since LLMs make it trivial to plan arch/tests for all the code changes you wouldn't have had the energy to do it for.

  • One thing I like about framing this as maintenance cost is that it moves the measurement boundary. The usual AI coding metric is something like accepted diff per hour, but the more interesting unit is probably future decisions created per hour.

    An agent can reduce typing while increasing the number of things nobody really owns later: rationale, invariants, tradeoffs, half-meaningful tests, files that changed because they were nearby, etc. The PR can pass and still leave the team with more intent to rediscover.

    The useful agent workflows I keep coming back to are less about "write more code" and more about making every change come with a maintenance handle: what invariant changed, what should fail if this is wrong, what files should not have changed, what rollback looks like. It feels slower in the moment, but it gives future-you something to grab onto.

  • I think AI is great for the soul destroying boring stuff that makes me want to quit my job like wrapping legacy code in test cases. Hey I’ll take on any idiot who’s willing to do that job, even if he’s artificial.
  • You can only type at 50WPM and read one file at a time, the LLM doesn't have the physical limits, use it at your advantage so you can actually focus on the work that matter
  • The strongest signal I have seen for whether AI actually reduces maintenance cost is whether the developer treats AI output as a first draft or a final artifact.

    When I use AI tools on existing codebases - understanding unfamiliar modules, generating targeted refactors, writing migration scripts - the maintenance burden genuinely drops. The AI is working on code I already understand architecturally, so I can evaluate its output quickly.

    The problem shows up when AI generates greenfield code that nobody deeply understands. That code still has to be maintained by humans who did not write it AND did not design it. At least with code another human wrote, you can reason about their intent from naming, structure, and commit history. AI-generated code often lacks that legibility because the "author" had no persistent intent across files.

    The article is right that we need to measure maintenance cost, not just velocity. In practice that means tracking time-to-understand and change-failure-rate on AI-assisted code vs. human-written code over months, not days.

  • There's a third mode that works better: structured phases (scoped to each feature, like humans do). (Plan phase => human reviews plan) => (Implement phase => human reviews diff) => (Test phase => tests run). The current TUI tooling gives you the option to do this type of bite-size scoping but you have to enable plan mode and not auto-accept edits. I've been taking the (enhanced) phased approach out of the default toolchains, having discrete phases (even simple plan=>implement=>test) that loop while capping tool access and edit sizes and that's been really promising in the realm of obtaining better agentic coding quality
  • I really like this question:

    If you could wish for a codebase, which codebase would you wish for?

    If you think a second on that question, you’ll realize you probably not wishing for a super feature-rich one, but an easy to understand one, quite close to what you have now. One that is easily to maintain and extend, depending on the upcoming business challenges.

  • > an easy to understand one, quite close to what you have now

    oh, you sweet summer child... I wish I had one of those

  • Code doesn't exist in a vacuum though.

    Code bases that you "work in" (maintain, etc) solve real world problems, and solving those problems should trump cleanliness every time

    Codebases that are clean are typically showcase examples that sit on a shelf to be admired and appreciated.

  • Same with code reviews.

    I wonder if AI could make code reviews more presentable.

    for example, with human code reviews, developers learn quickly not to visually change code like reflowing code or comments, changing indent (where the tools can't suppress it), moving functions around or removing lines or other spurious changes.

    And don't refactor code needlessly.

    also, could break reviews up into two reviews - functional changes and cosmetic changes.

    by m463
  • These are problems with a code review tool. Not a code change problem.
  • First Agent I used: Do a proper code review of the changeset, it adds comments in my merge requests. Then the junior devs paste these into their IDEs and loop forever :-P
  • https://github.com/ReviewStage/stage-cli looks like an interesting start on that subject.
  • Do any refactorings in separate reviews, and say things like "REFACTOR_ONLY:", with a rule that none of the code changes behavior.

    That makes reviews a lot easier. The review starts from "nothing should be changing" and then reviewers can pattern match on that.

    Otherwise, the reviewer is re-evaluating every line of code to make sure nothing has changed. That's really hard to do properly.

    The version control systems I've worked with have allowed queues of changes, each one reviewed independently. As I'm developing, if I need a refactor, I go up a commit, refactor, send out for review, rebase my in progress work and continue.

    I send out a continual stream of "CLEANUP:" "REFACTOR_ONLY:", and similar changes with the final change being a lot smaller than a big monster of a change.

    Your reviewers will appreciate the effort.

    Plays the metric game (if you're working in that type of org) without being evil too.

  • My team has been using AI to add code, but also to aggressively remove old deprecated code. "Is anyone still using this? How does this get called" is easier to answer when you can toss your FE, BE, and entire codebase at an agent and let it create a map of your software project. IDEs can do this in a single language to some degree usually in a single project, but RPC, REST, etc... break some of these tools in a lot of IDEs.
  • Two things I'd add

    1. software doesn't only have tech maintenance - there is also user support and it increases as software grows.

    2. I'm not convinced maintenance costs scale linearly. And even if it scales linearly, you will eventually get to a point where maintenance takes up all your time.

  • You think it scales super linearly? Could make sense, with the mainta8nance of not just the parts but how they interact with each other
  • In my Dconf'24 talk "Software as investment" I proposed a basic framework based upon a value function (compositional) for each piece of software. This framework doesn't really need an update due to AI, apart from the (unrelated!) cost model being updated depending on how good AI is at maintenance. Apparently it would do 1.7x the number of bugs, but perhaps it fixes them faster too? I don't know.

    Seeing software as investment avoids speaking about "technical debt" by speaking about "value", a liability just being an asset with < 0 value. When software exits the high-margin world of yesterday it needs to develop a precise definition of what software deserves to exist, economically.

  • Is this the talk? https://youtu.be/YBZ6JFrfuiM?si=6ZdZph8GxOy-OLHZ I'm curious to see it!
  • > Seeing software as investment avoids speaking about "technical debt" by speaking about "value"

    People already see their efforts as an investment, but that doesn't stop Debt from accruing over time. There will always be parts in your software that could have been written better, and that's Debt.

  • I did not see your talk but this summary somehow seems wrong.

    I would say there are two types of software debt. Dead code/useless features not providing value, which is in my experience easy to excise and rarely really causes issues, and the badly written code, which is providing value.

    The term software debt is usually used in the second case because you have to pay it for delivering new value to the product. The debt was introduced in the past when another value was being added and it was added in a way that increased coupling, reduced cohesion, etc. Let's just say that it was implemented badly, for many interpretations of badly.

    Now, if I want to add this new value then that previous bad implementation is causing issues, because of unsolicited side effects, of difficult to reason about logic, etc. So, now, I have to pay the debt, by refactoring, or by changing the logic in tens of places (which further increases the debt).

    Tech debt was never really about functionality that does not need to be there and is not providing value, because you seldom pay it, or it's relatively cheap to pay it. The problem is when you have to rework the old feature, still providing value and should continue to do so in the same manner, just to deliver this new value. That's the expensive tech debt.

  • Insightful. Agree with this take.

    Unfortunately, maintainability is simply bucketed as a "non-functional" requirement.

    Maintainability (and similar NFRs) should actually be considered what preserves and enables the delivery of future functional requirements -- in contrast to framing non-functional requirements as simply "how" the software must do what it does vs. the "what"/functional requirements that "actually matter".

    From that standpoint, if a steady flow of features/improvements is important for a project, maintainability isn't really a non-functional requirement at all, and amounts to being a functional requirement, in practice, over anything except the shortest of time horizons.

  • The maintenance cost argument cuts both ways. We ran into this building our own project AI moves fast, but the bugs it introduces are weirdly hard to spot. Not the obvious stuff. The logic that looks completely reasonable until three weeks later, when something breaks in production, and you trace it back to a subtlety the AI got wrong. My honest take: AI doesn't reduce maintenance costs, it shifts them. Less time writing, more time reviewing. And reviewing AI code is harder than reviewing human code because it's fluent and confident even when it's wrong. Whether that's a net win depends entirely on how good your team is at reading code vs writing it
  • Forget the term “non-functional”. Who wants software that doesn’t function? Use Kevlin Henney’s terms: operational and developmental characteristics. Maintainability is a fundamental developmental issue.
  • > amounts to being a functional requirement, in practice, over anything except the shortest of time horizons

    Right! The unfortunate thing is that many software companies don't seem to think much further than a quarter ahead, not really.

    Sure they might have a product roadmap that extends for a year or two into the future, but let's be honest. Often that roadmap is mostly for sales purposes, not engineering planning purposes. Product and engineering will pivot if sales slump. The earlier in the company's lifespan, the more likely this will happen often

    However if companies get out of this startup mode then they should start to stabilize... But many don't. They continue this pattern of short sighted short term planning, which means product stability remains a low priority effort.

    Ultimately I guess many companies just either do not have the resources to build good software or do not actually care to