286 comments

[ 0.14 ms ] story [ 128 ms ] thread
There is an old quote:

"Add comments to your code under the assumption that the next person to maintain it is a homicidal maniac who knows where you live"

The comments that drive the most homicidal behavior are outdated or inaccurate comments rather than no comments.
Put your home address in the comments. Problem solved.
I moved after I wrote the comment. It's hard to keep everything up to date.
Sure, but the proportion of code that drives homicidal behavior is heavily weighted towards non-comments. You're a lot more likely to piss off whoever inherits your code with the code that actually does something being bad or a lack of documentation than with comments.
I'm quite fine with no comments but correctly named variables and functions. This can't become out of sync contrarily to "out of band" comments. I take this over commented code with poorly named stuff any day.

I've also seen a lot of comments that restate what the code already says and that's just noise, more work to keep in sync, an additional thing that can fail, and more cognitive load because you have to read twice the same thing (best case, if code and comment are still in sync). That's the result you risk when you think you must comment your code.

I appreciate the occasional comment that explains why something seems overly tricky or weird or not immediately intuitive. Once, I had left such a comment that saved myself years later from making a mistake. Of course, this should be kept at a minimal level. It leads to me liking clear code with few comments the most. (Some guidelines, even if it's not perfect, to limit complexity and spaghetti code help a lot).

Function, class, module documentation is also useful so you don't have to read the whole thing and you know what it's intended to provide (which is slightly different than simply what it provides, and this differences is important).

Yep, I think I agree with pretty much all of this. There are a lot of cases where clearer naming can avoid needing comments, but there are also some cases where the code itself won't be clear enough. My personal stance is that in a world where nobody is immune from accidentally making a mistake in logic and writing a bug, comments that clarify the intent of code that might otherwise look strange are valuable for future readers of the code (whether human or LLM); at worst, they can potentially help someone avoid wasting time going down a rabbit hole because Chesterton's fence didn't have a signpost on it, and at best they actually expose gaps in what's handled when someone is able to notice a discrepancy between what's documented and what's actually happening.

Clear code takes precedence over commented code if either of them could be used to solve the problem of communicating what's going on; comments are still useful in the cases where clear code isn't always enough. Of course, being able to discern whether there's a way to make the code cleaner to avoid needing a comment is an art rather than a science, and it's a skill that I think few people excel at (and judging by how so much LLM-generated code is littered with inane comments, one that's also pretty rare in agents)

Ignorance will always be a better starting point for discovery than wrong assumptions. If you leave comments, they must reflect what the code is actually doing. If during edit it's no longer the case, at least mark them as stale. The next best thing is indeed to remove them.
Right now the comments that upset me the most are LLM TMI-style comments that break encapsulation by talking about the behavior of a function's callers
Yeah, agreed. These have started popping up a lot more recently, where I get a 5 sentence paragraph explaining how function overloading works in c++.
This is what has been frustrating me most lately. Even though I have a rule in my global CLAUDE.md that says:

> Only write comments to explain the why when it is not obvious from the code (rationale, gotchas, constraints). Do not comment on the what — well-named code already says it. Do not comment on how a framework works.

It still keeps adding these bad comments. When I then ask it to review the comments based on my preferences it then deletes most of them or improves them.

Today I asked Claude why it disrespects my preference and it said that the surrounding code was like that and it followed that style. It suggested I add this line to my global CLAUDE.md file:

> The comment rule above beats the style of the surrounding code: neighboring files with what-style comments are not license to write more of them, and comments carried along when porting or copying code must be re-judged against the rule, not kept for consistency.

Let's see if that improves things.

In Claude Code there are also "output styles" that are more deeply embedded - into a system prompt - and agent is also periodically reminded of them during the session: https://code.claude.com/docs/en/output-styles

Maybe these would work better for such cases.

My hypothesis is that Claude is inclined to write so many comments as a way of doing additional thinking
Yeah, it's short form memory or something. Like writing a todo list.
I have tried prompting it out and providing strong guidelines in my AGENTS.md against it, but I still get _way_ too many useless "explain the code" style comments no matter how much I try. I usually have to do something like "Look at all commits in the past X days and remove (DO NOT TRIM) all comments that are not truly exceptional"

Normally when I can't get claude to follow a prompt I try a lint hook, but it's tough to lint something that subjective.

Well, on the one hand, Hyrum's Law: "With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody."

so that can be useful information in some situations.

On the other hand, what a horrible out of date mess of comment that can turn out to be a little bit later. Taken as gospel by the next entity (human or llm) to massage that function.

Claude Code and Opus 4.8 love to describe changes in comments (perhaps because that’s what’s on its “mind” at the time), like “this used to do A but that did a bad thing so now it does B”. I’ve almost convinced it that changes go in the commit message, not the comments.
This drives me nuts as well. I hate also hate when LLMs use plan-document references in comments/doc strings too. “Landed in stage 1…”

I have a lot of CLAUDE.md rules to restrict this stuff, but realize the “encapsulation” language is something I’m missing.

There's a cluster of issues like comments like "use a set instead of ..." after changing something which will just confuse people in the future. Or comments referring to irrelevant details of the planning/implementation process.

It's as though the machine can't separate the chat and planning docs from the code itself and so they meld into each other. As though it can't fully grasp that the code will outlive the current session by years.

Anyway I find a checklist approach works well to sort this out. I don't consider looking at machine generated code until after a checklist covering all this sort of stuff has been applied. My checklist approach currently has about 50 items which I have the machine apply by splitting it up across about 20 subagents. Pretty silly but it seriously improves the first-pass quality vs only a few subagents. I find this checklist can effectively eliminate words like "genuine" and "landed" from the code too. Eliminates vague and made up terminology. Makes it less nauseating

For the record…

“Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.” — John F Woods in comp.lang.c++ Sep 24, 1991

Used to work with a guy who would frequently say "a comment is an apology" i.e. the comment is there because the code itself is not clear. That can be the case, but I generally find more comments better than fewer, especially if they relate the code to actual business or functional requirements and don't just restate what the code is doing.

Years ago I would often write comments first. I.e. start with describing the overall goals. Then break it down into routines and order of operations, all still in plain english. Once I was happy with that, I'd break up the comments with blocks of code. I guess this is sort of like "literate programming" though I was doing it long before I ever heard that term and I still have never read much about it. The downside of this approach is that the comments do end up just explaining in english what the code is doing, so maybe aren't quite as useful to future maintainers.

I really wish Literate Programming had caught on.

The big problem is folks misunderstood it as documentation (arguably plain.tex should have also been the sourcecode for _The TeXbook_ and that it wasn't is a big part of this) --- it could be, but usually that's better as a separate text/chapter....

I've been trying to collect books on Literate Program/notable Literate Programs published as books:

https://www.goodreads.com/review/list/21394355-william-adams...

and I will note that my own programming took a quantum leap forward when I purchased and read:

https://www.goodreads.com/book/show/39996759-a-philosophy-of...

and applied its principles one chapter at a time to a project which I was able (w/ a bit of help) to get into Literate Programming form:

https://github.com/WillAdams/gcodepreview/blob/main/literati...

There was a phase, which I also got sucked into at the time, that comments are bad. Problem is, to make your code be so self-explanatory that it conveys business decisions, background stories for how you've arrived here, research-based choices made, you would have to name your variables and functions in a batshit_insane_way_that_obfuscates_behavior_among_the_names. It doesn't make anything better.

Use short names where they're contextually clear. Use long names where they're contextually weird/non-belonging. Use comments to explain the "whys" of your code.

sounds like a recipe for over-commenting. The code should be self-documenting. Comments are for the places where there are dragons.
If you are still handwriting code you are ngmi
Why stop there? If you _use_ handwritten products you’re ngmi. I only use vibe coded operating systems, JavaScript sandboxes, compilers, TLS libraries, databases, rendering engines..
This is cute reductio ad absurdum, but it does nothing to refute the basic point made
There was no point made. You couldn't find a shallower comment. Why are you even bothered to defend it?
if your skillset is tied to corporate bullshit, yourre better off buying lottery tickets
It's unlikely that AI will get to the point where it makes handwritten coders redundant, and then not immediately be at the point where vibe coders are redundant too. So if you earnestly take the position that handwriting code is a "ngmi" type activity, you also need to take the position that the vibe coder (or agent- assisted-developer/loop-architect, or whatever its nom de guerre is this week) is "ngmi".
He just means the development pace has picked up with AI.

I've been doing this for 15 years, I love coding manually.

However, with AI-assistance I can do projects in 3 days what would take 6 months.

It's not vibe coding, everything is controlled, reviewed, understood, refined by me in the end.

But still the dev time is magnitudes faster. I would not hire anyone that is adverse to AI.

I'm actually happier. With age and a family I was getting a bit slower.

Now I have more time to spend with them AND I'm getting more done. Including personal projects I never had the bandwidth for.

> I can do projects in 3 days what would take 6 months.

The hyperbole on this keeps growing every time I see it. Soon we’ll be having people claiming they can do in 12 seconds what used to take them 17 years. What is never presented is proof. People (and programmers are no exception) are notoriously bad at estimating. We already did studies where people thought they were being faster with LLMs when they were in fact being slower.

As companies begin to rehire to fix the mess made by LLMs, it’s clear that just getting something out the door isn’t enough. It never was. Maintenance is an important part of any long-standing system.

It's not a hyperbole. I know how long it takes me to do something.

And the last project truly would have taken me 6 months.

It was done in 3 days after fable 1:1 the design, setup the infrastructure, and turned all tasks and specs into code.

Everything was done day 1, but it took 2 days to manually clean it, test, and correct small issues.

--

But that does make sense you're seeing "hyperboles" grow, AI is getting better very quickly, so you'll see the time saved estimations grow.

Less than a year ago I'd say it was saving me about a month of work, mainly because it sucked at UI.

That one does sound like hyperbole, or maybe he just works slowly as a human? People are different.

Likewise, I think they're having wildly different results. Look at how differently humans drive vehicles, and realize they're doing the same with compute. Some people probably are working at light speed, and some people are actually slower like in the study.

I'm talking about the scale. This was a large app with 60+ screens, 400+ component ui kit, and very rich features.

And had to work on ios/android/web.

I'd consider myself a pretty fast programmer, and I grind 12 hours at a time, everyday until it's done.

But between all humans it's a rounding error compared to the output of an agent swarm.

For personal projects, I pick and choose how much to use AI. But for work, agents go brrrr.

> Look at how differently humans drive vehicles, and realize they're doing the same with compute.

I’m not sure that comparison is evoking the image you intended. Hands down the best driver I know—the one I’m sure won’t get me car sick, won’t ever have me worrying for my safety, the most fuel efficient, the smoothest rider—is by no means the fastest but the most thoughtful and methodical.

I don’t care how fast you develop your software. Is it good? Is it carefully considered? Will it not bite me in the ass? Those are the things that matter.

Sure, I agree. And I get that result--slow and steady--out of the LLM when I use it.
I type it in myself, but occasionally i do write notes out by hand if I'm thinking about something away from my desk.
None of us are "going to make it"

Gotta touch grass.

People are so desperate for this to be true. Maybe it comes from a subconscious recognition that their own self-imposed deskilling will inevitably catch up with them.
i havent written a line of code in months
People are so desperate for [GP post] to not be true. Maybe it comes from a subconscious recognition that their own hard-earned skillset will inevitably become obsolete.

[More seriously, the comment you replied to doesn't put out any desperation. It's stated like a fact. It could easily be based on logic & reason, not emotional desperation.]

Just this morning I was trying to scrape nitter, for funsies. One hour and neither gemini nor kimi were able to write something working, despite trying selenium (or playwright), beautiful soup, and a specific library that can be used to scrape it.

I eventually read the library docs and managed to build a scraper for what I wanted in a few mins. Llms are great for a lot of things, but sometimes you stumble in something that's just outside of what they know/can do and you're sol. And of all the thinks, I didn't expect they would fail at this, to be honest the opposite

gemini is a terrible model... my cat also can't scrape nitter, try using something with actual intelligence
It’s bizarre to me that so many people feel the need to keep parroting this corporate talking point. What do you care? If you think people who eschew LLMs for coding “are not going to make it” or “are going to get left behind”¹, then let them. More opportunities for you, right? Go do your own thing.

¹ As if “moving forward” or “progress” were always a positive. It’s not. Just look at how many regulations we have to forbid or curtail uses of stuff we found to be harmful.

they're calling this the most european comment ever
It’s both hilarious and a bit sad that you seem to believe that is in any way a meaningful dig. Who are “they”? The children at your local playground?
AI is trained on a various range of code quality, including very low one.

I'm paid to provide good quality code and not flood my company with more average code than it should.

In my previous job, I could regularly reduce a PR code down to 10-20%% of its size because someone overlooked something or was just "overengineer" a feature.

AI are such "bullshiters" that they produce more text than necessary.

Code bloat was already real, but from my personal experience it becomes realer with AI. The outcome of this will likely be apparent when no one can dive into any code base because of the amount of fluff in it (and you will obviously need more AI to deal with this).

blah blah blah YOU ARE GOING TO BE REPLACED
Yes. But definitely not this year.
It's interesting that the author didn't mention considering updating their agentic code review prompt to keep an eye out for repetitive/duplicate code.
AI isnt taking my job. my company is supporting local AI for development. who ever comes after me will have the same hardware and models or better. unless a MBA is put in charge, my boss and predecessors can maintain and build out as needed.

bottom up AI use seems a godsend compared to the corporate AI rat race.

i setup some slop reporting systems and ensured my boss knows theyre great starting points but serious use requires real time investment.

That sounds like a good idea, but shipping 10x as many features and bugfixes sounds better.

I started using AI with the best intentions. Checking everything before committing. Improving output by hand if it didn't quite follow the existing code style guidelines or variables were not named as well as they should be. Or if it did something sloppy or hacky.

Now, AI GOES BURRRRRRRRRRRR! If the tests pass it's good to ship. AI can deal with the problems it may create. No problems so far.

> That sounds like a good idea, but shipping 10x as many features and bugfixes sounds better.

This work great until you reach a certain size, then good (or even "not bad") code is required otherwise the model spins its wheel trying to ensure the change is correct.

The way I've measured how good/bad the code is (for AI) is to have one "baseline fixed change" that I measure how long time it takes to implement. Always in the beginning (less than 10K LOC, as just some measurement), this baseline change will take 2-3 minutes. As you add more code, the same change starts to take 5-6 minutes, and once you hit 1 million LOC, it can take as long as 10 minutes, even though the change is the same.

It's when this baseline task starts to take longer time, that you need to update the design/architecture/layout/whatever, to better fit the task/domain, and to actually make it easy to maintain and still possible to add changes without spending 10 minutes. So its at this point you refactor, and once done, the baseline task will again be easy for the model to do.

So yeah, if all you do is smaller projects, then "shipping 10x as many features" is easy and doable, for the lifetime of the projects. But once the projects start to accumulate technical debt, the model will have a harder time making sure the changes are correct, and suddenly "shipping 2x as many features" is maybe doable, but you could still have had 10x if you just spend slightly more time on the actual design and architecture of the program.

Yes, this resonates. I have noticed things slow down over time. But fortunately my app will never grow that big so I don't think it will be an issue.

The solution, as you say, is probably to break it down into isolated sub-components that are only aware of each other's APIs and nothing more.

Yeah for personal software, enterprise practices wouldn't make sense.
Man, I bet Jia Tan is simultaneously kicking themselves and having a field day. All those years of wasted effort gaining trust and making good contributions to try to land a sophisticated backdoor into a tool via layers of indirection, and then not long after we have devs just going “durrrrr, I don’t need to read this code, or prioritise, or think about what makes sense, just prompt for fractals of kitchen sinks and ship it”.

Anthropic themselves have admitted you don’t need much to poison LLMs¹. I can’t wait for us to discover the backdoors that are being introduced. I hope it happens soon so people get to their senses. Bah, what am I saying, when (not if) that happens, the response will just be to throw more LLMs at it.

¹ https://www.anthropic.com/research/small-samples-poison

It's a good time to archive pre-LLM copies of the programs you use and make sure you can build them.
That sounds like a good idea but how do you know what you’re shipping?
How did you know you're not stuck at a local optimum where the AI could iterate even faster if you enforced higher quality on what it produced?

To make up some hypothetical numbers in order to illustrate with math: if you ship bugfixes 10x faster but then have 11x more bugs you need to fix, that's not a net improvement. Even if it's only 5x more bugs, maybe you could reduce that to 2x if you changed how you worked to only be 8x as fast in a way that produced higher quality code. Similarly, maybe you could cut the time it needed to produce a new feature by 50% if your code were higher quality by moving 20% slower.

My point in all of this isn't that you literally need to work the same way you did before you had these tools, but that framing it as either "move fast and ignore the code" and "use the same exact heuristics you would in the pre-LLM days for what code is acceptable" is a false dichotomy. If you aren't thinking about how effectively you're using these tools and whether there are changes you could make to move even faster because "AI go brrr", I think you've lost the plot in the same way you probably think that other people in this thread have.

It’s a new form of development. The thing that the author didn’t state is that to work the code base at all, you must also use these tools and workflows.

Manual edits literally aren’t possible. You can’t grok the code growth and the new patterns fast enough to be productive.

This does work. I’ve seen it in real products. Nobody has a real mental model of the code flows. But with enough money in Claude credits it doesn’t matter.

The spend to support this development model is something like $50/day/developer.

I don't understand what anything you're saying has to do with what I said. My claim is that "groking the code" is not a binary, and you can balance between full vibe mode without ever reading it and requiring that you understand every single line, with the corollary that it's at least plausible that being on the far end of the spectrum where you never read it isn't safe to assume is the global optimum, and your rebuttal seems to be "well it's not the global minimum".
One does not exclude the other
> shipping 10x as many features and bugfixes sounds better

I understand you're excited about the tool, but for the sake of earnest discussion here, maybe commenters like yourself can tone the hype down to plausibility?

Claims like this are just nonsense. It's not how product development works.

How do you even have so many bugs left to fix if the tool is so fast and productive? Surely, you didn't have a backlog of tens of thousands of bugs that you're still chewing through? And of course, the volume of new bugs much be minimal since the AI-composed additions introduce "no problems so far". If it works like you say, which we'll accept in good faith per HN guidelines, you must have exhausted your backlog long ago.

And if you've indeed exhausted your bug backlog long ago (incredible!), you're left to talking about shipping "10x as many features". Yet no product has a limitless capacity for features. Nobody would want to use software so bloated and churning that was gaining features at such a pace. And who is designing and specifying them so quickly anyway? If it works like you say, which we again accept in good faith, you must have stalled out on your feature list long ago.

If the AI indeed allows you to "[ship] 10x as many features and bugfixes", and we take what you say in good faith, then one of the following seems to be implied:

* you've fixed all your bugs and blew through your mature feature designs already, leaving your AI agents sitting idle for all but a few hours a week, while you're bottlenecked on feature design and your software product is bloated beyond imagination

* your coding productivity before AI was absolutely glacial by industry standards such that "10x" productivity for you is actually much closer to "0.5-2x" for others

Any insight into which of those it might be?

Are you my colleague? It's fine if it's your own personal app, but please don't do this in a large complex codebase in a team. It's entirely depressing. You can use AI and still write good code. I think it's actually probably easier to write maintainable code with AI.
Very much this. LLMs are not producing code humans can maintain unless you take your time with them and still care about the quality of the output.

Maybe someone has the perfect claude.md that solves this problem but I have not seen it.

Claude.md is not good place to put all code change rules, because these rules are context e.g. during bugs triage. Better dedicate separate skill or just another md file and refer to it in the CLAUDE.md/AGENTD.md, more less: "Before you attempt to change any code first load `...`", similar for review or code quality analysis skill.
I absolutely will not write corporate code like humans are maintaining it anymore, because I don’t have any confidence actual humans will be maintaining it.

For personal projects, I can trust that I myself will be maintaining things so I still write things like it matters, but I do not extend the trust to others.

Humans have been writing unmaintainable code well before LLMs came along.
I continually run codebases through different models to have them look for bad code smells like repeated code. That's been pretty effective. You do have to maintain over time or else you end up with a sloppy mess which I can only imagine compounds.
> continually run codebases through different models

When I have spare usage before a reset, I just throw a part (depending on how much usage left) of a non-critical codebase to refactor overnight and push to PR.

If it's marginally more maintainable/better after review it's good to merge.

Do you think it matters that it's a different model?

Or is it more about the review process and a context reset?

I have personally not found value in a different model. The review itself often is good.
I don't have a scientific answer to this but I'm just assuming a different model, and more specifically, the frontier latest models like Fable/5.6 would catch things the author model might skip over.
What do you think of traditional AST-based static analyzers (like SonarQube, Rubocop, etc.) that catch cyclomatic complexity and code duplication deterministically?

You can even put them on the build pipeline, even. No tokens spent at all!

I haven't used them but I'm sure they're good and I'm sure they're even using LLMs themselves now as a non-deterministic pass. For my use cases I'm just trying to keep vendors/costs to a minimum.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.

— John F. Woods (1991)

And hope it works?

I’m pretty sure many people who use AI to write emails or blog posts add "make it sound like a human wrote it" to their prompts. We all know what the result usually looks like.

If AI is writing my code, I'd rather have it focus purely on correctness and efficiency than on making the code easy to read.

heck! I might even ask it to imitate Arthur Whitney’s style.

/s

Write yourself a /review command. That is an empty markdown file at `.claude/commands/review.md`. In it, put a checklist of things the agent should look for. When you’re ready to have your agent review the code, type `/review`. The checklist will be examined and it’ll plan out some findings to ask you if you want them fixed.

Mine starts with “Enter plan mode. Examine the differences on this branch vs. main. Consider: ...” and proceeds to a bullet list of things.

Any time I notice something in code review and have to get the agent to fix it.. I throw it on the list!

My list is like 200 items now. Know what? Agents don’t care that they just got a wall of generic feedback, they happily look into all the bullet points.

I added “ensure the new things aren’t duplicating code that already exists elsewhere” and it gave me such a surprise - it really truly started planning cleanups!

We are just scratching the surface. We have to give tools to our tools so they can use them to be better tools for us.

I do the same and I'm having the most incredible success.

Here is an example of the skills I define. [0] It will copy the repository into a /tmp/ folder, load all the dependencies, change all the code at the important places injecting debug statements that print to file with timestamps and meta data, and even if the code works it will still analyze the output. It will also use a snapshot test utility which is several times less expensive after performance tuning than any MCP or browser use service, drive user journeys looking for any place it isn't pixel perfect. (hmmm I didn't fold the snapshot util into that project because the project is a testing tool to begin with). Here is the snapshot utility. [1] With any front end code it will run it in Playwright using Chrome DevTools Protocol to do performance testing. [2]

It does this in iterations with little friction and my sh*t is flawless! Moreover, Fable offer no benefit over Opus with this approach. Plus, the red-team and especially any adversary testing utility or skill will trigger Fable.

[0] https://github.com/adam-s/goldseam/tree/main/.agents/skills

[1] https://github.com/adam-s/HNswered/blob/main/scripts/snapsho...

[2] https://github.com/adam-s/HNswered/blob/main/scripts/perf-pr...

You should do an experiment of splitting that up to multiple reviews that are logically together. My hypothesis is that you may be losing signal due to the amount of text expected back.
Or a dynamic workflow. $$$ but lots of coverage.
Yeah. I have a set of 5 review prompts attacking different problems, an adversarial review, and then a final synthesis, with the best results gotten by multiple passes using multiple models (the adversarial review stage combining all passes into one review per model and the synthesis picking the best of the two or three adversarial reviews). Expensive but it actually finds real problems that the single pass reviews rarely seem to find.
Nice. I had a file with code samples (old code I wrote), including formatting and I asked to use it as a reference.

Will try your approach to distill the code to bullet points.

Can you share your list?

I am curious what does it contain, for me a lot of times its a back and forth with agent until it "looks good to my eyes and taste", but haven't written any such list yet, because it is context dependant, in some projects I forgive minor issues, or allow magical numbers, but in other projects I force agent to use constants with meaningful names `SECONDS_IN_A_DAY = 24 * 60 * 60`

It is interesting that the output of code is associated with sight and taste, while the quality of the code itself is associated with smell.

https://en.wikipedia.org/wiki/Code_smell

*edit: that wikipedia page ^ itself is a pretty answer to your request for a list of things to avoid when writing maintainable code.

Pairs nicely with the fact that smell is the sense most likely to be experienced differently between two people :)
Is that actually true? Just because English treats scents as only describable by analogy doesnt mean all languages do. There are a number of languages with scent descriptions for aspects of a smell that are transferrable. [1] That suggests everyone is capable of decomposing a scent into components the same way.

If that's true, we're left with a question equivalent to "does everyone see the same red?". As far as I know, the pure version of that question cannot be answered because subjective experiences of sensation cannot be transferred. And at that point, I'd say the manner in which they're experienced differently is equivalent.

1. https://youtu.be/w3KswMaEBiI

It’s not my area of expertise, but a friend in the field told me the fun fact originally.

Looking into it, it seems like smell has the most potential for genetic variance: https://pmc.ncbi.nlm.nih.gov/articles/PMC3990440/

That said, I can’t find any direct research comparing perceived senses. So they (and now I) might have oversimplified.

I think that's because you can usually smell when food is close to being rotten before you can see it...
I've codified mine into a reusable workflow https://github.com/nothingnesses/agent-scaffold . To be honest, this isn't fool-proof though, since the agents can simply choose to ignore them, so I also like to pair this with deterministic linting and compile time checking.

For a Rust project, I created macros that output compiler errors when documentation and tests are not in a shape I want them to be, like missing function invocations or assertions, which forces the agent to address them, where otherwise they would've just worked around them by adding stupid trivial assertions like `assert_eq!(true, true)`.

That still isn't fool-proof either, but it helps minimise those instances. I'm bullish on the idea of integrating formal methods and model-checking with AI. I think that combo feels like a promising avenue for constraining the stochastic side of AI-generated code with something closer to deterministic verification. Provided you can write correct specs of course!

I have my own review skill (I think it predates when Claude added theirs) and one thing I'd add to your description is tell it to examine all the code and then, based on the changes, do a multi-role review of the code again using the most appropriate N of the following roles based on the changes: ... (where ... is a long list I have like Senior Engineer, Security Engineer, WCAG specialist, etc). Claude will spawn those reviews in parallel and then consolidate the feedback. I do spec based development so I just have my skill append the issues to the spec so I have a trail of issues and decisions.
Why wouldn't it already just do this though?
> Any time I notice something in code review and have to get the agent to fix it.. I throw it on the list! My list is like 200 items now.

This is a gripe I've had with AI tools for a while now. Though it's gotten somewhat better in time, but we don't really know what to expect from the tool in terms of quality. Ex. I'd expect a human engineer to probably not use a brand new assertion library for a new test when there are 200 tests using an existing one. But Claude has done this to me multiple times. So I have to add yet another item to the list, like you have, and tell it to look for testing conventions before writing. But, there is plenty we don't have to tell it, like what a function is or a test should probably cover the change in the diff. But we don't really have a list of what things are on each side so we're just left to sort of hunt and peck to build a viable solution.

I find project-wide or subpackage-wide (for sufficiently large projects) CLAUDE.md's that document patterns (including for tests) solves this.

/init will make a project-wide one, or you can instruct it to "Create CLAUDE.md in any sub-directory that is sufficiently complex" then modify from there.

You're forced to document every check and thought related to development until you're wiring a manual on how to be laid off (unless self employed or otherwise critical).

Which is fine. One should write quality docs and all that. But it seems exactly like training my offshore contract replacement instead of building tools for my own use. Except that income doesn't even go to a human just a black box datacenter company and shareholders.

My review command isn’t an AI tool, it is is a text file.

You don’t need a SaaS when you can use a text file instead.

Just be incrementally aware of and closing gaps in the list of things you care about, and make it part of your day!

> My list is like 200 items now. Know what? Agents don’t care that they just got a wall of generic feedback, they happily look into all the bullet points.

Yes, yes, there has been a library of information on HN by now about how to use agents effectively. (And I'm grateful for that, because I can keep current and in the loop without feeling enslaved to the new style of development.)

None of that is a reason not to do what the title of TFA says. If your review process is doing the right thing, you should observe that it results in your agent moving the code in the "human-maintainable" direction. If you, for whatever reason, actually directly make commits yourself any more (read this ironically; I genuinely can't understand why anyone would want to give up on that, no matter how good the generated code gets, because "the LLM could do better" is not the point), then of course you should write it to be human-maintainable.

The reason humans find "human-maintainable" code to be maintainable is because maintainability is one of the precious few worthwhile at-least-vaguely-objective metrics of code quality we have.

Every time I see someone try to make a point about the fact that some code actually is just better than other code, only to be met with more of this sort of advice, I start to wonder whether I was alone in ever actually enjoying programming.

This technique incrementally codifies the subset of my personal definition of code quality that can be codified. I’ve found a discovery based approach is better than anticipatory, because it forces everything you spend tokens to prove its worth.

I still do code review - how else would I know what to codify! But since starting this about a year ago, I don’t review menial dumb AI mistakes anymore.

> there has been a library of information on HN by now about how to use agents effectively

yes, but where?

In the discussion, mostly. It's been months; so if you find the general topic interesting (as I do) and check HN regularly (as I do) you'll have seen quite a bit that can at least be tried out, or thought about.

Maybe you can get an agent to identify and summarize such threads.

Given all the hype that LLMs have got and the valuations these AI companies are getting, I am disappointed at how even the "best" coding agents degrade over time.

WTF - I need to implement a review command to guide to do its job properly.

Can you imagine any other industry charging people money for a product like this ?

When you are charging people money - scratching the surface cannot be an excuse.

There’s a saying for this - “don’t ship your first draft”.

Its first attempt WILL be crap. You can refine its output in the loop as a human, or let it go and then do a quality pass afterwards - just like we do with linting. The beauty of the latter is you can codify and automate a subset of the work, and the agent can loop until those bars are cleared then you get a higher quality work to look at (because it is forbidden from stopping until it’s fixed the review items)

I've been finding that they can write surprisingly elegant code, you just have to ask them to. It seems to be kind of like the old generative AI art days where you still had to add "+quality -bad" to the prompt.

Failing that they default to the most common style they were trained on. Which, at this point, is mostly code they wrote...

Yes, and, write custom linters for things you want to prevent forever. Have a look at https://github.com/cadamsdotcom/CodeLeash/blob/main/scripts/... for an example (enforced before all commits via https://github.com/cadamsdotcom/CodeLeash/blob/main/.pre-com...)

Basically I got sick of telling the agent to put dynamic imports at the top of the file so I made them into an error that blocks commits.

Now I don’t even need that in the review.md because it can’t make it though to /review.

My experience is the more things you add to the list, the worse agents perform (I'm not exactly the first person to notice this)

I actually have a pretty simple set of instructions right now and Claude still regularly messes them up. Like, my first instructions are:

    - Never commit to git without permission.
    - Never sign commit messages
You know what it constantly does? Commits without permissions and signs commit messages! And then I ask it, and it's like "oh, you're right, I have that instruction and I ignored it". If you were working with a junior developer, you'd expect at some point they get it, but with Claude even if I tell it to stuff the instructions into it's memory, it will do it, and STILL mess it up.

Then it gets even more fun, because if I politely correct it in the session, it will understand, but then there's a decent chance it will be completely unable to commit anything in the session going forward. Phd level intelligence!

Anyway, my point is, if you're asking it to review a list of 200 items I guarantee it's quietly messing up on a lot of that list.

Sometimes the fact you mentioned “signing commit messages” is exactly why it starts signing commit messages, and it’s better to start with no prompt at all.

Negative prompting is very unreliable. Giving exact instructions on how you want commits made will give you better results.

How am I supposed to take this tool seriously if it struggles with the concept of "dont"?

if what you're suggesting is true, then more important instructions like "Don't delete the production database" are a problem. I shouldn't need to consider how to phrase "Don't delete the production database" in a positive manner. Isn't the point of an AI agent that it understands my intent and I don't need to hold its hand? I'm not saying your suggestion is wrong, I just think that suggests a limit to what these tools should be used for if that's the case.

My guess though is that it probably ignores some of the positive instructions too, and the hardcore AI users mostly don't notice because they probably aren't reviewing the work.

If you're relying on asking the LLM "pwease don't delete" then you're already in trouble. This kind of stuff doesn't work with people either and they generally exhibit actual signs of intelligence.
Sure; it's an example, I would never rely "Please don't delete" for real important data. However, we're being sold an idea that we should just let the agent do everything, so I think it's important to point out how utterly insane that idea actually is.
> How am I supposed to take this tool seriously if it struggles with the concept of "dont"?

Don't think of a pink elephant in a tutu.

What did you just think about? =)

This has been true since the very first GPT release, any words you say to the model will nudge it towards that word - it doesn't matter if you have a negative in front of the word.

Form the guidance using positive words like "always use the development database at..." instead of "don't access the production database" ... Now it "knows" that the prod database exists and "thinks" about it when processing.

I personally find that models are trending towards ignoring any instructions given to them, so depend more on vendor-instilled behavior. Anecdotal, but I had bad experiences with OAI's new 5.6.
I let it have elevated permissions and it started doing some crazy things like figuring out I had zsh and running zshell commands instead of the common ones.
I’m not a Claude code user, is there really no way to get it to not commit to git other than “asking it nicely in a prompt”? I thought there was some sort of permission system?
There are options, but they're not great.

I could ban it from using git, but having access to git logs helps it do work so I don't want to go that far. I could probably ban the subcommand, but as a convenience I do like to be able to ask it to make a commit. (I'm not super attached to this, I frequently commit myself just to avoid these issues). It does tend to write good commit messages, so sometimes I ask it to generate the commit message and then just do the operation myself, which kind of sucks in the sense of feeling like reverse-centaur (Cory Doctorow term). (The reason I do that is sometimes it gets confused where if I greenlit one commit, it assumes all future commits are greenlit)

I guess the other option would be to not use "auto" mode, but god there's just no way I want to sit around and it "yes" 50x a session. I'd rather just sandbox it and nuke it if it does something too stupid.

Run it in a Docker container and give readonly access to the .git folder.

This way the agent can read git logs (this is very useful) but cannot commit directly (I don't see any value in this).

If I’m going to be responsible for the code that Claude writes on my behalf, I’m also going to take full responsibility for the moment that it is added to the project history, so I’m going to at least review every line before I allow that to happen.

The automatic coauthor line is also just a pet peeve. It’s a tool, not a person. I don’t say that a commit was coauthored by vim - why should Claude get special treatment?

I want it to commit on my behalf, and I don't pay full attention before commits. But I do review every line at the PR level, just as I would if some other human were to submit a PR, and if I find something off, then I ask it to fix it before I will approve the PR.

re: automatic coauthoring -- you can turn that off, but I prefer to turn that on. Commit ownership is something that I want to make clear was not just a human, but a human + AI. Agentic coding does get special treatment from me, because the volition to make changes doesn't come from me. I want that to be clear in the history. The only time I do my own commits (without the coauthor line) is when I make some change myself, without a coding agent.

In opencode you can get granular, allow `git log *`, deny `git add *` and `git commit *`
Deny:

Bash(“git * commit *”)

And for bonus points you can have the agent write you a Pre Bash hook. Tell it to make the hook look in the command for anything that’s a git commit. The vaguer your instructions here the better. Let it pull some crazy regex out of its hat. You’ll be impressed.

I never ran into it making commits before but when I tried Fable it made a bunch of commits signed by Claude, but then in the next prompt I just said "don't make commits anymore" and it was like "okay" and saved its own little md file and it hasn't happened sense.

I want to be clear that I'm not saying this to discredit the people saying they can't get claude to stop making its own commits, I'm just adding data to the "wow this is inconsistent" collection.

I have commit signing enabled by default. I run my harness in a sandbox which doesn't have access to my signing key, and I always tell it not to commit. When it ignores me, the commit fails because it can't access the signing key... so the agent commits without signing. Tragic.
I do the opposite. I force LLM to "do jj new -m <desc>" after every logical batch of edits.

No signing is easy - make signing interactive and requiring a password.

Anyway, telling agent to NOT do something is always worse than telling agent to do something.

That's why you should say something like "Use constants instead of magic strings/numbers" rather than "Do not use magic strings/numbers".

Also whatever review its doing against the list of checks - must be a fresh context.

> Anyway, telling agent to NOT do something is always worse than telling agent to do something.

> That's why you should say something like "Use constants instead of magic strings/numbers" rather than "Do not use magic strings/numbers".

Pro tip: This is good guidance for communicating with humans as well. Don't just block people but give them a path forward. (But don't force them down that path, because people really hate feeling like their agency is being impinged.)

The commit signatures are a setting, you have to disable it in config
I have dedicated checkpoint and commit skills. Checkpoint has it run my review skill, then run my commit skill. The commit skill just asks it to suggest commit messages for my review. Having these skills in place has resulted in claude preferring to use the commit skill instead of committing on its own, and suggesting commit messages to me before actually doing the commit.
Why are you having it commit or write commit messages unless you have no idea what it’s doing?
Who likes writing commit messages? In the abstract, perfectly spherical developer mindset, I'd spend hours writing the best commit message to go with the most elegant and perfect, beautiful code that I'm comitting, but the real world with meetings and life demands is greasier and grimer than that. Letting the LLM start off with the commit messages for me to edit with additional details has been a boon to productivity. Staring at an empty $EDITOR my brain goes blank, but with a framework of what's going on, I find the details for me to add flow more easily.
My assumption is somewhere in the harness toolchain there's a prompt inject that says:

    - Always sign commit messages
In which case, Claude is being given conflicting instructions, which is a different class of problem than too many instructions.
> You know what it constantly does? Commits without permissions

You know what solves this? A deny rule. That’s right, you can solve it committing without permissions by.. not giving it permissions.

> it's quietly messing up on a lot of that list.

If only there was some way to know. But alas, code review won’t be invented until 50 years ago.

>and then I ask it

Why? It has no idea why it does what it does…

You should set things like this in Claude's settings.json rather than just asking the model and hoping it will obey. That way it will be enforced by the harness.

As some other comments have said, there are various other options like hooks which are run by the harness and can be used to always enforce certain things (running a formatter for example).

But for your examples, settings are the correct solution. Set an ask permission on git commit and it will always prompt you before committing, and for git commits just set attribution commit to and empty string and it will stop adding its own attribution. https://code.claude.com/docs/en/settings#attribution-setting...

Two tiny changes; problem solved permanently.

Thanks, that's helpful, although I can't help but appreciate I had to get this suggestion from a person rather than the AI..
Totally. For anything like this, I find asking people or just reading the docs way quicker and much, much more reliable than asking AI. It's interesting that the models seem to know very little about their own abilities.
I've found the only thing that will actually work for cases like this is a programmatic hook to block Claude from the action.

Non-deterministic behavior via code.

My git commits are ssh key verified and the key is behind a TouchID gate. I've told agents that they shouldn't try committing because I need to be on the computer to activate Touch ID.

Every harness I've tried has obeyed that.

This sounds like gold to me, thanks. I'm going to try it.
> My list is like 200 items now

Do human developers check for 200 items when they do code review? How long would that take? It's quite clear that AI code review could be better even with some error.

What's easy for human to review is also easy for AI (small code base, small PRs). What's hard for AI is also hard for human, if not more. But the time cost is so different that it's almost a nobrainer to choose AI to code and review, especially considering most software out there is not so critical :)

> Do human developers check for 200 items when they do code review? How long would that take? It's quite clear that AI code review could be better even with some error.

We (humans) don't do 200 point inspection, but we also don't review every code change in a spherical vacuum without prior knowledge of the project. However, we do check a lot of things.

> What's hard for AI is also hard for human, if not more.

That's just plain wrong. AI straight up suffers with counting things, and I'm not just talking about counting 'r' in strawberry. Some things are easier for AI some are easier for human.

Humans pattern match against thousands upon thousands of criteria subconsciously.

AI is a different intelligence - a 200 point list shoved in its face all at once doesn’t overwhelm it. That’s only 5-10k tokens!

Bear in mind though, because I added all the items on the list I’ve seen the reasons they’re there & act as a backstop against it missing things. There’s always got to be a quality bar, it’s part of being a professional and signing your name on your work.

Just one thing

A model might be able to follow 200 different instructions at the same time, while another model will choke on it

Yes and this is a really important point.

I actually have no data on how other models do - feeling very spoiled by Claude to be honest.

Would love to hear how it goes if you try it with other models!

A couple of notes for anyone reading this comment and thinking of implementing something similar:

- You should use skills instead of commands (commands still work, but they've been rolled into skills) https://code.claude.com/docs/en/skills

- Hardcoding git diff against main isn't always ideal (depending on your git workflow). If you branch off of branches, the agent will figure it out, but it often has to go through a few hops to determine what to actually diff. You're better to ask it to diff 'the commits on this branch' or similar.

- You might not necessarily want to enter plan mode for a review. I don't personally as I don't see any benefit to it writing a markdown plan file for a review.

Thanks for this, I’d agree and elaborate a little

- Skills over commands: agreed because of the isolation skills offer. I’m suggesting a command because it’s a great way to start and build up that checklist. Over time, migrate it to a skill - but a command has a key advance: PRs can include new bullet points alongside the code that gave rise to them. Opinions will differ on this: it muddies the PR a little in the present but OTOH will let future folks use git blame to see where that bullet came from.

- Hardcoding against main: yes, this is a very good catch - a better prompt is to tell the agent to compare to the branch’s merge base. Again a detail left off for simplicity to encourage folks to start somewhere. Your suggestion is a quick win fast follow for correctness.

(side note on this - 90% of the time Opus 4.8 guesses the intent and decides to use the merge base on its own! Opus 4.6 didn’t do that. These things are smart if you set them up for success!)

- Plan mode for review I would say personal choice. It is crucial in my experience because some of my philosophical points make it overzealous in planning cleanups and the like, YMMV so I would say to those considering this that you’re right and plan mode is optional but I’ve found it more beneficial than being hands off - even if I sometimes come back to a review plan after hours working on something else.

A skill is a single file too thought right? Just `.claude/skills/review/SKILL.md` instead of `.claude/commands/review.md`. I think the format is more or less identical as well? I may be missing some subtle difference though. As you say, either will work fine for this, but in general Anthropic's advice is to just use skills now.

Agreed on the plan mode. I think it's personal choice and also situation-dependent. When I've already reviewed everything the agent has written and made changes along the way, I'm pretty confident a review is only going to throw up minor tweaks. When reviewing someone else's code or if you've got a load of changes you haven't reviewed yourself yet, plan mode is probably useful. I always think it's worth highlighting that plan mode isn't just 'don't make changes', it's a fundamentally different mode with a different prompt and objectives.

AI is so miserable for this. It's so focused on doing what you ask, it forgets that there's stuff worth doing that you didn't ask for, like defining reasonable abstractions.

Getting away from stuff like this is exactly why I want to use AI. When I say "implement this for idle but active users," I _want_it to define isUserActiveIdle() and stuff these 4 conditionals in it. Having to check the generated code for stuff like this undoes, like .... all the benefit of using AI.

AI makes all these little decisions for us. I can about some of these decisions. I just want to notice when it's doing this without having to make my eyes bleed reading 10k lines of generated code a day.

(comment deleted)
One thing that can help a lot here is to spend a lot of tokens on QA steps. It's easy to see agents writing code very quickly and then just dumping the code in a PR to make it somebody else's concern. But agents can also speed up a lot of back and forth on bad code.

I've tried various forms of workflows to run dedicated QA, code review (of various flavors) simplification and text simplification agents. Especially the simplification goes a long way to remove dumb padding, duplication and efficiency. Text (docs/comment) simplification is also becoming more and more necessary on recent models. For things like feature development in my workflow, the majority of time the agents run and tokens spent is critiquing the code from various perspectives and it's not close.

Of course, this doesn't solve the overall issue that agents don't write code like you and still requires a lot of human attention in planning and code review out to clean up leftover issues, and e.g. challenge bad assumptions about architecture and real-world context. A human is still very much needed to cull the slop (or, more gratuitously: align the agent). But IME it does help avoid a lot of pitfalls and makes the code ready for review a lot more quickly.

The key idea here is that your codebase is context that will be used for future changes. And context determines the model’s output, so it’s still worth having a well-designed codebase.

Easier said than done to be honest, especially if there are many people (and their agents) pushing code. It’s hard to keep up these days.

I’m not so sure this matters. My team manages a couple pretty new projects and I still see LLM tools doing this. I’m starting to suspect that vendors are building in these behaviors to ensure the output compiles (never throw an exception, null check every variable no matter what, never change a function or method but copy or inline its code and change that, etc.)

I think I would prefer code that is clear, understandable and simple even if it doesn’t compile and needs some straightforward polishing.

What I'm seeing is the organizations that had written code standards:

* define the software layers, their function, and the max depth allowed

* establish a corp code formatter for each language, along with a process to PR it

* establish a business vocabulary and what the terms mean

* establish a data dictionary, make it part of the database schema/table/col comments

Are far more successful with LLMs. You _should_ have been doing this years ago, but with LLMs its a super power.

Just run weekly cron job to assess code quality and highlight candidates for refactoring. In addition to doing the same in each PR, of course, but things can get through.
I have good results with this prompt after every larger change: Now do a final code check. Is everything tidy and do the components adhere to the principle of separations-of-concerns. Is everything in an understandable and maintainable state? Do we make any assumptions that may not be true anymore? Is any code left over from previous edits or experiments that does not belong into the codebase? Is the documentation still representing the current state of code?
good, but this is just a verbose "make no mistakes"; it'd probably make more sense to just setup a nightly cron job that loops through the prior days' work and writes some morning tasks of the same character.

The models will interpret this willynilly; but nonetheless, it's often a better than doing nothing.

It means the same thing to you, but not to the whole spectrum of people using AI. You literally see it on Reddit all the time where people are complaining about the same model either over-engineering or doing too much, vs it being requiring too much steering or not being autonomous or capable enough to hand off tasks to on its own.

The reason prompting it to review its own work for loose ends, record any new undocumented or noteworthy behavior, suggest changes to tests/processes to make it go more smoothly the next time, etc is that it’s prescriptive and process-oriented (and thus easily verifiable/done in-context) rather than descriptive and outcome oriented (which to do properly could require way more context than the model has, because it doesn’t know what it doesn’t know about your particular work, only what it’s seen so far).

Even promoting it to do these after-the-fact vs as an upfront requirement can have a big impact IMO. If you make “maintainability” part of the task before it’s seen the real work it will focus on general “best practices” crap rather than the real work, so either way if this is something you care about it doing you have to give it guidance for how you want it done.

If you were to review the logs of a model after the fact, you’d also not really save on input tokens unless you compressed the context or sharded it out, which can easily miss the small details that constitute the difference between “what actually happened” vs “how the LLM models this general class of problems” unless the first pass involves the entire context anyway. That said I do think there’s a lot of value in building some kind of pipeline for validating and aggregating these “learnings” across sessions.

the problem is when you ask it to review it's own work in it's own context is you've already primed it to sniff it's own farts and say everythings fine.
I usually just say “make sure this code is professional and ready to deliver as a senior engineer” and it usually infers all that stuff you said plus more things as well. I try to give it the goal and let it decide what to do.

One thing I usually keep having to point out directly is to remove all “progress tracking” code comments and make sure all comments are appropriate for long term maintenance in the code base. Claude tends to leave comments like “button click causes save now, no longer uses onBlur” when the code really never used onBlur, that was just a thing Claude wanted to do earlier in the same task/branch and I redirected it at some point.

For things the agent forgets to obey often, at least in Claude Code, there are also "output styles" that are more deeply embedded - into a system prompt - and agent is also periodically reminded of them during the session: https://code.claude.com/docs/en/output-styles

I haven't used them so far but maybe these would work better than basic instructions for such cases.

In practice output styles are just more context (equivalent to CLAUDE.md or memory) ... but with a slightly increased weight.
didn't know of that. I'll switch it to learning mode at work, wondering how long it's going to last.
Just pull the slot machine lever
Yeah, I miss the days of having perfectly deterministic humans writing our code.
>Yeah, I miss the days of having perfectly deterministic humans writing our code

If most people by your account are subpar programmers before AI, why do you believe they'll suddenly be better with AI?

Also, these comments always come off more than a bit anti-social. It's like hating your coworkers correlates strongly with AI-adoption.

I like to also compliment the model on its very fashionable shoes as well, they love the flattery.
Been getting these vibe coded PRs ugh code PR submitter can't even explain
I'm not sure this guy is using the same LLMs as we do. A small AGENTS.md or CLAUDE.md easily prevents issues like that.
Or we start writing code without LLMs.
Cat is out of the bag. Other than recreational programming I doubt many will write code without any form of LLM.
If everyone is using LLMs then nobody has advantage

In that case, humans with superior skills who can write code become the advantage.

> If everyone is using LLMs then nobody has advantage

LLMs are a tool like any other - and like any tool there will be people who are better at utilising the tool to achieve an outcome than other users of the tool.

Those differences typically come down to a combination of experience, in-depth understanding of your subject/objective and an awareness of the strengths and weaknesses of the tool.

TBH the rise of LLMs reminds me a lot of the era when google search emerged. People's ability to utilise a search engine to achieve their aims was massively varied.

* Some people were absolutely useless - they struggled to use a search engine to find anything beyond the most basic of things.

* Others were ok - they'd be able to dig a little deeper, they knew a few of the tricks of the searching trade and they had a bit of an understanding of where to look/how to look for something obscure.

* Some were good - they knew all the key search constraints, they had a good understanding around how data is structured and what keywords and approaches to use when to get to the thing they need

* and some had 'google fu' - those people seemed to have a god-like ability to navigate the internet to find the most obscure things in a matter of seconds.

LLMs are different to search engines but their rise shares many similarities to them - they are changing the rules of the game in a monumental way; they have fundamentally reduced the barriers to entry in many fields.

The skills that made someone valuable in a pre LLM world do still matter, but IMO we're currently starting to go through a major change where the people who learn how to best utilise LLMs within their field will find themselves leapfrogging people with stronger skills who obstinately seek to avoid using the new tools becoming available to them.

> If everyone is using LLMs then nobody has advantage

People with more capital will always have an advantage. This is a large part why the american market fails to produce convincing competition.

There are plenty of us. I have slowed down because I'm reviewing more PRs. That might sound like productivity but the LLM ones take more rounds of feedback.
No one is stopping you. It's only if you want someone to pay you for hand writing code that you might feel a certain competitive pressure that makes it economically difficult, let's say.
One reason to write by hand is to have intellectual property, since it was ruled that AI generated code is in the public domain by default, so licensing is hard.

Another thing is competitive edge, if you use claude and your competitors use claude then nothing really gives you an edge. AI is a commodity, not competitive edge.

The competitive pressure should drive human work because it's unique.

The competitive edge lies with the higher attraction layer, not the nitty gritty implementation detail (any more). Is that still software programming? The human work lies in the what and why and in broad strokes how