I joined TetriXX AI wanting to ship code, not freight, and I spent my first weeks doing it the way that felt fastest.
I worked on the part of Freya where the invoices come in. Every charge on them is reconciled against the rate that was actually agreed with the carrier, and new carriers arrive constantly, each billing in its own shape. Some send a PDF that was printed and scanned back in, some send a spreadsheet, and some send a text file that turns out to be a CSV wearing a different extension. The same client will send three formats depending on which of their systems produced the document.
The path I built instead of the one I should have found
A few weeks in, a genuinely new kind of document landed on me: a credit note, which is what a carrier sends when it has overbilled you, or when goods came back, or when a charge turns out not to apply after all. Instead of asking for money it reduces what you already owe, which is why finance teams track them closely and why they cannot be treated as an edge case. Structurally, a credit note is an invoice with the signs reversed. I built it its own path through the system.
The reason was not that I thought a separate path was cleaner. It was that a separate path was the only thing I knew how to build correctly yet. Slotting a new document type into the existing pipeline means knowing where the seam is, and that means understanding the whole of it: how a file gets classified, what each stage promises the next one, which of those promises I would be quietly breaking. A parallel path asks none of that of you, which is exactly why it is so appealing when you are new, and exactly why it was the wrong thing to build. It also sidestepped a real irritation: the pipeline was shared, and anything off to the side could be reviewed and merged without landing in anyone else's way.
It took me a few days to notice that I had written a second copy of almost everything around it. Another way in, another way of deciding what a document was, another way of assembling the result and handing it off. The genuinely new part, the piece that actually read a credit note, was small, and everything surrounding it already existed a few directories away. I deleted the branch and rebuilt that one piece as a component inside the pipeline I had been avoiding.
Then I overcorrected. A little later I wrote a deliberately general converter, the kind built to turn anything into anything, and a reviewer pointed out that it had exactly one caller and probably always would. My careful instinct had been wrong, and my reusable instinct had been wrong in the opposite direction, and I had no way of telling in advance which one was about to fire.
A distinction from 1986
That is when I went looking for something better than instinct, and found that someone had already named what I needed, decades before I ran into it.
Fred Brooks ran the development of IBM's OS/360 in the 1960s, at the time one of the largest software projects anyone had attempted. It arrived late and over budget, and he spent much of the rest of his career working out why. He wrote it up in a book whose central finding still gets quoted well outside software: adding people to a late project makes it later. The idea I needed comes from a later essay, published in 1986, and it splits the difficulty of building software in two.
Some of it is essential: it comes from the problem you are actually solving, and no amount of cleverness removes it. The rest is accidental: it comes from the solution you happened to choose, and it is yours to avoid. Reading a credit note is essential, since it is genuinely new work that somebody has to do. The second way in, the second classifier and the second assembly step were not the problem being difficult, they were difficulty I had added to it. The distinction is forty years old, and the people I worked with who had it applied it in review and mostly called it taste. It stayed a matter of judgment because the cost of writing the wrong thing was high enough to slow everyone down anyway.
What changed is who is writing
I spent my time at TetriXX AI working alongside coding agents, which is normal here, and that is where the old distinction stopped being philosophical.
An agent asked to support a new carrier's billing format will build a new path for it, quickly and with complete confidence, for exactly the reason I did in my first weeks. It does not know the system well enough to find the seam. Unlike me, it will not know it better next month either, because each session begins without the accumulated sense of where things belong. So it reaches for the option that requires no knowledge, which is the parallel path, and produces accidental complexity faster than any team of people ever managed to.
I am not the only one to have noticed. Andrej Karpathy, who has done as much as anyone to popularise writing code with AI, built nanochat, a compact from-scratch implementation of a ChatGPT-style model, almost entirely by hand, using autocomplete and nothing more. He has said he tried coding agents on it several times and they were no help at all. His explanation arrives where I did from the other direction: the code is dense and original, and it looks nothing like what the models saw in training. With no established pattern to reach for, they reach for the patterns they do know, and you get scaffolding around a problem that never needed any.
In an industry with one document format, you could absorb that. Freight does not have one format and is not going to get one. Every new carrier, every credit note, every invoice pack is another shape, and if each one costs a new path then the paths multiply until nobody can safely change anything. The cost is never in the volume flowing through the system, it is in the number of distinct routes that volume can take.
Asking for a check instead of taste
So I stopped trying to encode judgment and wrote down a check instead.
Before writing anything, list everything the change adds that has a name: a class, a table, an endpoint, a setting, a value. For each one, name what in the system already does that thing. Whatever you cannot name is the real work. Everything else is a duplicate, and the right move is to delete it and use what is already there.
It asks nothing of anyone's taste, only that you go and look, one name at a time, which is something an agent will do reliably and tirelessly if you tell it to. The case that taught me the most was one where the wrong answer looked entirely professional: I needed a list of people who should receive a weekly report, and a dedicated table with the code around it is a clean design you could defend in any review. It is also what I would have built in March. Running the check left exactly one thing unnamed, and it turned out to be a single value in a list that already existed.
What is scarce now
Writing code used to be the expensive step, which is why producing it felt like producing value. That is no longer where the cost sits. When a competent implementation of almost anything is a request away, the scarce thing is knowing what not to ask for, and the only way to know that is to know what you already have.
That knowledge used to live in the heads of the people who had been there longest. It cannot stay there now, because the fastest writer on the team is the one with no memory of last month. So it has to be written down: not as principles in a document nobody consults, but as a check that runs before the first line gets written. None of this is solved. Getting that knowledge out of people's heads and into a form an agent will actually consult is one of the open problems we are working on, and every new carrier we onboard teaches us a little more about which parts of it can be written down and which still need somebody to go and look.
Freight will keep inventing formats. What we can control is how many paths through our system each new one costs us, and for a while the honest answer was one path per format, because that is what I knew how to build.
I still want to ship. I have just stopped counting the code as the thing being shipped.
Freya audits freight invoices against contracted rates, across whatever formats your carriers actually send. See how it works · Talk to us



