I Kept the Decisions and Gave Away the Typing
A CSV parser, a junior developer, and the wrong place to cut a task in half.
I cannot point to one person. That is the first problem with writing this down.
There is no single developer I can name, no particular afternoon I can put a date on. It happened often enough over twenty five years that the faces run together. Someone came to me stuck, I looked at what they were stuck on, and I built enough of it to get them moving. Then I went back to my own work feeling like I had done the right thing, because I had.
One of them still surfaces, though.
We had a client with a public website we had built for them. Product catalog, entity model we had designed a year or so before, all of it stable and working. They had another internal system holding the authoritative product data, and they wanted that data on the site. The export came out as CSV. A decent number of fields, each one needing to land somewhere in the entities we had already built.
The work was a parser. Read the file, map the columns, build the objects, handle duplicates, validate that the required fields were actually there. Straightforward in shape, fuzzy in the details, the kind of ticket that looks small until you are inside it.
The developer assigned to it was junior. Solid for his experience, the sort you hand real work to because he would finish it.
This was years before anyone was pasting a CSV into a model and asking for a parser back. If he got stuck, he was going to Google it, or read the docs, or find a Stack Overflow answer from 2009 and work out which parts still applied.
I had written a lot of file parsers by that point. So I sat down and knocked out a start. A few hours. The file was open, the stream was reading, three or four fields were mapped into the entity, and I wrote one validation check as an example of the pattern. Not tested properly. Not finished. Deliberately not finished. I left most of it for him.
Then I sent it over and went back to my own work.
He finished it. It worked. The import ran, the products showed up on the site, and nobody mentioned it again.
A few hours of my time against what would have been a few days of his. The client had a date. I knew this problem cold and he did not.
And I did not hand him a finished routine. I want to be clear about that too, because it is the part I was quietly proud of at the time. I held back on purpose. I left him the bulk of it.
Here is what I actually left.
The remaining fields, which were the same operation as the first three, repeated thirty times.
The duplicate handling, which was the one genuine open question in the ticket, except the database already had a constraint on it. So the answer was not something he had to reason toward. It was going to arrive as an exception at insert time and he was going to catch it. That is debugging. Debugging is a fine thing to learn. It is not the same as deciding what a duplicate means for this client’s product data and then going to find out whether the schema agreed with you.
The validation was closed by the example I wrote. One instance of a pattern turns every remaining case into copying.
The entity mapping was closed by the three fields I had already mapped, which said, in effect, these go here.
And the question of what the ticket even was, whether this was a parsing problem or a modeling problem or a business rules problem wearing a parser costume, was closed before he opened the file. Because a file already open and a stream already reading answers that question. It says: this is typing. Follow the pattern.
So he typed.
I left him the bulk of it, and the bulk of it was grunt work. Every question in that ticket that could have taught him something had already been answered by the time he saw it. Some of them by me, one of them by the database, and the largest one by the shape of what I sent.
That is the part I got wrong, and it is not the part I would have guessed.
What I could have sent instead was smaller and would have cost me fifteen minutes. A link to the docs for reading a file in C#. A note that there was a stream API worth understanding before he picked an approach. And a question: which of our entities do these columns belong to, and what makes a row a duplicate here?
That version takes him longer. Days, probably, and some of those days are him going in a direction that does not work and coming back. From the outside, those days look identical to being stuck. They are not. They are the only part of the ticket that was going to leave anything behind.
I have written a lot about choosing difficulty. Doing the hard version on purpose. Staying in the confusion instead of reaching for the thing that ends it. All of it aimed inward, at myself, or at you doing it for yourself.
That handoff was a decision about somebody else’s difficulty. His formation, his hours, his chance to hit the edge of what he knew and go find out. I spent all of it and it cost me nothing. I was not even the one who would have had to sit through the slow days. He was.
That is a strange kind of authority to hold over another person’s week, and I did not know I was exercising it.
The feature shipped. The client was satisfied. He finished the work and I imagine he felt fine about finishing it, and I felt fine about having unblocked him. Every visible signal available said this went well.
Compare that to the mistakes that actually teach you something.
Years ago I built one feature in a stable system using a framework nobody else on the project used, because the standard approach felt boring. That one buckled under production load, cost weeks to rebuild, and cooled a client relationship in a way I could feel in meetings for months afterward. I learned it immediately, because it hit me in the face.
This one thanked me.
I still do not know what it cost. Maybe nothing. Maybe he wrote five more parsers and the sixth one taught him everything mine skipped. Maybe he is better at this than I am by now. I am not going to claim a harm I cannot demonstrate.
But the absence of a bad outcome is not evidence that the call was right, and a mistake that produces no evidence in either direction is one you can go on making for twenty five years without anything ever stopping you. No test catches it. No review raises it. No retro has a column for it. And the person on the other end cannot see what he was not given, because you cannot see the shape of an absence when the absence is all you have ever worked in.
I wrote that sentence once about my own first four years, working without a senior developer anywhere near me. It points in both directions.
The whole thing came down to a single seam, and I cut it in the wrong place. I kept the decisions and gave away the typing.
None of this had anything to do with AI, which is exactly why it is worth writing down. This was one person with a few hours and good intentions, deciding by hand where to divide a task, and dividing it in the place that removed everything worth having. The tools did not invent this failure. They inherited it. What I did occasionally, for one developer, while trying to leave something behind, is now available instantly, to anyone, on request, with no intention behind it at all and nobody on the other end deciding which half to keep. The seam has not moved. It just gets cut a thousand times a day now, by something that is not thinking about it.
So the question I did not ask then, and try to ask now, is not whether I have time to help.
It is whose difficulty this is, and which half of it I am about to spend.
👉 If you enjoy reading this post, feel free to share it with friends!
Or feel free to click the ❤️ button on this post so more people can discover it on Substack 🙏
You can find me on X and Instagram.


