Naming things for a tired human

Checked 22 Sep 2026 · By Luke Czak

ArticleUnderstanding AIFree to read

An identifier only has to be unique to a database. A name has to be unique to a tired human reading it back, which is a much stricter requirement.

I run more than one project at once, and for a while every task inside every one of them was identified by a short code: a letter, a number, nothing more attached to it. It was perfectly unique. No two tasks anywhere across any of my systems ever shared an identifier, and for a database that is the entire requirement, discharged completely and without any ambiguity whatsoever. What I had not accounted for was that a database is not who actually reads the identifier back later. I am, usually late in the evening, usually tired, usually with several of these open in different windows on different screens at once.

The failure showed up the day the same short code turned up in two different projects at the same time, for two entirely unrelated pieces of work that had nothing to do with each other, because the numbering in each project restarts from its own history and has no idea the other project even exists. Reading either code in isolation told me nothing about which project it belonged to, which meant the code itself was useless as a name the moment more than one project was in play at once. I had built an identifier that satisfied uniqueness within a single system and then handed it to a human operating across several systems simultaneously, where uniqueness within just one of them was never the property that actually mattered to that human in the first place.

The deeper issue is that a short, unique code is optimised for a very specific kind of reader: one holding no other context, comparing two values for equality, and nothing more than that. A tired human at the end of a long day is a much worse version of that reader, in every respect that matters here. I am not comparing values for equality when I look at a code on a screen. I am trying to reconstruct, from the name alone, which project this is, which branch it lives on, which of several similar copies of the same work might be the one actually sitting in front of me, and the exact moment I am least able to do that reconstruction from memory is the moment a bare code forces me to do it anyway, with nothing else to go on.

What actually works is a name that carries enough of its own context to disambiguate without making the reader supply the missing part from memory under pressure. Not the shortest unique string that technically identifies the thing, but one that states the project and the location alongside the task itself, so the name answers the question a tired reader is actually asking rather than the narrower question a database was asking when it needed nothing more than a primary key. The two problems look similar on the surface and are not the same problem at all: a machine needs to tell two rows apart, a person needs to tell two entire situations apart, and a name built only for the first job routinely fails the second one silently, which is about the worst way a naming scheme can fail, because nothing about the failure announces itself.

I think the lesson generalises past task identifiers to almost anything a human has to read back under pressure: a log line, an error message, a filename buried three folders deep in a project structure nobody quite remembers the shape of any more. The test I now use before shipping any naming scheme is not whether two values could ever technically collide. It is whether I could still tell what a given value refers to if I were reading it for the first time in months, half awake, with no other context on screen and nobody around to ask. That is a much harder bar to clear than uniqueness, and it is the only one that was ever actually being tested every time a real, tired person had to act on the name rather than merely store it in a database somewhere.

Comments (0)

Sign in to comment.