Why are users saving grants?
Not how many.
Not which ones.
Why.
I had the data. I had the events. I had months of usage history.
And I couldn’t answer it honestly.
That’s when it clicked:
UX debt turns into data debt faster than most teams expect.
“We’ll clean it up later” is one of the most expensive sentences you can say while building an internal tool.
It sounds reasonable. Responsible, even.
After all, the UI can evolve. Users will adapt. And the data is still there, right?
That assumption is where things quietly go wrong.
I’m focusing on internal tools here deliberately. This failure mode hides best when there’s less polish pressure, fewer users pushing back, and a higher tolerance for ambiguity in the name of speed.
While building AIGrantMat…
Why are users saving grants?
Not how many.
Not which ones.
Why.
I had the data. I had the events. I had months of usage history.
And I couldn’t answer it honestly.
That’s when it clicked:
UX debt turns into data debt faster than most teams expect.
“We’ll clean it up later” is one of the most expensive sentences you can say while building an internal tool.
It sounds reasonable. Responsible, even.
After all, the UI can evolve. Users will adapt. And the data is still there, right?
That assumption is where things quietly go wrong.
I’m focusing on internal tools here deliberately. This failure mode hides best when there’s less polish pressure, fewer users pushing back, and a higher tolerance for ambiguity in the name of speed.
While building AIGrantMatch, I kept discovering that decisions I thought were “just UX” were quietly shaping the long-term integrity of the system. What started as small interface shortcuts hardened into schema constraints, analytics blind spots, and irreversible ambiguity.
By the time I noticed, the debt wasn’t visual anymore.
It was semantic.
Early on, I treated many user actions as signals rather than intent.
Bookmarking a grant.
Skipping a recommendation.
Revisiting something days later.
The thinking was simple: capture the raw behavior now, interpret it later.
That feels flexible. It avoids premature decisions. It keeps options open.
But data doesn’t get more expressive over time. It gets colder.
In practice, that meant staring at rows that told me what happened but not why.
A grant was bookmarked; but was it aspirational, urgent, or just interesting?
A recommendation was skipped but was that because it was irrelevant, overwhelming, or poorly timed?
Days later, weeks later, that context was gone. All that remained was behavior without meaning. Any attempt to recover intent turned into guesswork.
Postponing clarity didn’t defer work.
It pushed ambiguity downstream where it was harder and more expensive to resolve.
The design change that fixed this class of problems was surprisingly small.
I stopped treating user actions as events to interpret later and started treating them as intent declarations that needed to be recorded immediately.
Originally, bookmarking looked like this:
isBookmarked: true
Which tells you almost nothing.
So I changed the model to capture intent explicitly:
bookmarkReason: INTERESTED | APPLYING | TRACKING | DISMISSED
bookmarkedAt: timestamp
That single shift unlocked multiple things at once:
Analytics stopped relying on inference.
Filtering and recommendations became honest.
UX decisions stopped leaking ambiguity into the data layer.
Most importantly, “we’ll fix it later” disappeared because there was nothing left to guess.
This experience changed how I think about internal tools more broadly.
If a user action implies intent, that intent is data.
If you don’t record it explicitly, you’re choosing to hallucinate it later.
Once intent is captured at the edge:
UX gets simpler
data gets cleaner
and future decisions stop being archaeological exercises in reconstruction
Most UX debt isn’t visual.
It’s semantic and it compounds quietly until you can’t pay it down anymore.
No posts