Software for Strangers

We spent two years building software for people we had never met. On a recent trip to a client's manufacturing floor in Houston, we finally watched them use it. There is a big screen by the entrance showing the digital kanban board we built. Operators with iPads drag cards from station to station, and the screen updates in real time, giving the whole shop a live view of its own process.
Standing there, something clicked into place that we had always known intellectually but had never quite felt. All those tickets, all those features, all that code. It was always for someone. We just could not see them.
Imagining a user is not meeting one
We are reasonably good at imagining users. It is part of the job. We knew these were people who work with their hands, who are results oriented, who do not want software that is laborious or clunky. We were not wrong in the broad strokes. But imagining a user and meeting one are different things. What surprised us most was that they did not have a list of complaints. They were grateful that we took the time to look at their feedback and actually make changes. That landed differently in person than it ever had in a backlog.
Relational debt
Everyone talks about technical debt, the shortcuts in code that compound over time. There is another kind that kills systems faster. Call it relational debt. Technical debt is about the how. Relational debt is about the who. A system accumulates relational debt when the people it serves become abstractions, when nobody is watching, nobody is caring, and nobody is asking whether it is still right. The code keeps running. But the system is already dead. It just has not realized it yet.

We have seen the pattern over and over. An API pulls data, analytics sit downstream, and at the far end someone reads a report. When the feed breaks, that person notices and makes a phone call, because people in real jobs do not accept everything uncritically. But the systems nobody looks at, the ones with no active relationship, those break quietly and stay broken. We once had an async job fail for a month over a bad deployment secret, and nobody noticed because nobody was looking at that data over the holidays. The fix was not technical. It was making sure someone was always in relationship with the data.
Design is the distribution of friction
On that same Houston system, an IT manager was manually correcting ten to fifteen inventory transfer records every single day. Users kept doing them wrong. The frustrating part is that they could have been doing them right. They just were not. Here is a rule we live by: if a user is able to do something, they will do it, ten times out of ten. It does not matter whether it makes sense to you. It made sense to them in the moment, for some reason.
Design is the distribution of friction. You put friction where you do not want people to go, and you remove it from the path you want them to take. That is the whole job. So we rebuilt transfers with guardrails. You could not move inventory to a location that did not exist, or have the same item in two places at once, and type-ahead lookups made correct entries nearly effortless. Corrections dropped from fifteen a day to maybe one a month. People were not spitefully breaking the software. They had a job to do. Make the right path the easy path, and they take it, because they want it to be right too.
Competing models of desire
Users do not just want features. They want what their peers value, what their bosses value, what makes them look competent. The foreman values speed because he is measured on throughput. The manager values visibility because he is measured on reporting. Leadership values data integrity because they are measured on decisions. Those desires conflict, and the software becomes the place where they get negotiated. You can write picture-perfect requirements that are internally coherent and still ship the wrong thing, because they encoded one model of desire and the person on the ground operates from another. The only way to reconcile competing desires into one coherent interface is to talk to people, all of them, at every level.
Why this is the AI question, not a side issue
Analysts predict a large share of enterprise applications will embed AI agents by year's end, framed as delegate, review, and own. Here is the question we keep coming back to: could an agent have noticed that IT manager's stress, the weight of fixing fifteen records a day under pressure? Could it have understood that this was a human problem wearing a data problem's clothes? The answer is no. And if an agent cannot feel the weight of a problem, it cannot own the solution.
An agent working for no one is not working. It is processing. The spec, the acceptance criteria, the definition of done, these are all relational artifacts. They encode what someone wants. Remove the for whom and you do not just strip out meaning, you strip out coherence. Correctness itself is relational. Correct according to whom? Useful for whom? Done for whom? Keeping a human in the loop is not a safety brake bolted onto automation. It is what keeps software from floating into irrelevance. Software for strangers, done right, becomes infrastructure for friends. That is what the screen in Houston showed us.
