Saturday morning, 08:47. A sports hall in Bytom, Poland. Six hundred and nine competitors from across the country, six mats, and the draw has just been confirmed.
I open the tournament tracker I built three weeks ago. It shows: nothing.
Not a bug — not exactly. The draw exists in the API. 608 contests, 330 with fighters already assigned. My son Adam is fight #33, 1/32 round, -42 kg, against KANIECKI Feliks. The system knows all of this.
The live page shows dashes. “Znaleziono: 0.” Zero found.
I built this tool to answer one question: where is my kid, and should I still be nervous? And right now, in the moment it matters most, the tool is silent.
I open a notebook and start writing.
Observation 1: The Data Exists, But the User Can’t See It
The live tracker is built around mats. It shows what’s fighting on Mat 1, what’s queued for Mat 2. The architecture makes sense — during a tournament, everything is organized by mat.
But right now, between the draw and the first fight, no contests have mat assignments. mat=0 on all 608 entries. And the tracker, correctly, shows nothing — because it’s a per-mat queue view and matless contests don’t belong.
Meanwhile, the big screens in the hall show full bracket pools with names. Same data source. Different question.
The API has the answer. The tool doesn’t — because it was designed around the system’s structure (mats) rather than the user’s question (who am I fighting?).
I’ve seen this pattern in every enterprise AI deployment I’ve been part of. The data exists somewhere in the organization. The dashboard shows something. But the dashboard was designed to answer the system’s question, not the person’s. The executive stares at a wall of metrics and still can’t answer: are we in trouble?
The fix isn’t more data. It’s a different entry point.
Observation 2: The System Tracks Status. People Need Stakes.
09:16. Adam fights WIĘCH Aleksander on Mat 5. He loses by waza-ari.
I look at the tool. His card shows: 0W-1L.
That’s accurate. And completely useless.
What I need to know is whether Adam has another chance. In judo, there’s a system called repechage — if the person who beat you advances far enough in the main bracket, you re-enter the competition through a consolation path. Your fate is literally tied to your opponent’s success.
You need to cheer for the kid who beat your kid.
The tool shows a two-digit summary. It doesn’t track WIĘCH’s next fight. It doesn’t tell me whether repechage is still possible. It doesn’t say: “WIĘCH fights KROKER next on Mat 5 — if he wins, Adam’s path stays alive.”
I write in the notebook: “The system tracks status. People need stakes.”
Most enterprise dashboards I’ve encountered have the same blind spot. They show what is — revenue this quarter, tickets closed this sprint, model accuracy at 94.2%. They don’t show what it means for the person looking. Is 94.2% good enough to ship? Does this quarter’s revenue mean we’re on track or slowly dying? Is this sprint’s velocity sustainable or are we burning out?
The data is correct. The question it answers is not the question anyone is asking.
Observation 3: Same Data, Different Question
10:16. Adam’s teammate ROŻNIATA Mateusz is about to fight on Mat 4. Our tool shows: ZA 1 — meaning “next up.”
I glance at the official JudoManager portal. It shows ROŻNIATA at position 3 on Mat 4. Two fights ahead of him, not one.
Same data source. Same API. Different answer.
I dig in between checking mats. The discrepancy is in counting method. The official portal counts from the currently active fight: in-progress = 1, next = 2, after that = 3. Our tool skips the in-progress fight and counts from the next upcoming: next = 1.
Both are “correct.” Neither is wrong. They answer different questions. The portal answers “what’s the order?” Our tool answers “how many until mine?” But a parent sitting in the stands, nervous, counting — “ZA 1” creates false urgency. You rush to the mat thinking your kid is about to fight. He’s not. There are two fights to go.
I diagnose the code, fix it, deploy. Between fights.
The principle I write down: “A metric that’s technically correct but answers the wrong question is worse than no metric. It creates confident misunderstanding.”
I’ve watched organizations make strategic decisions based on dashboards that were technically correct and structurally misleading. Sprint velocity looks great — but it’s measuring story points completed, not value delivered. Customer satisfaction is 4.2 out of 5 — but the survey is only sent to customers who didn’t churn. The numbers are right. The decisions they produce are wrong.
Observation 4: The Surface Answer vs. the Actual Capability
09:52. Our IJF live tracker — tracking a parallel international tournament in Teplice — marks itself as finished. “Wyniki końcowe.” Final results.
But the tournament is still running. An entire weight category hasn’t started yet.
The tracker polled the IJF API, got 32 contests, all finished, and concluded: tournament over. Except the API only returns completed fights, not the full bracket. “All returned contests are finished” doesn’t mean “the tournament is over.” It means “these are the 32 fights that have happened so far.”
Digging deeper — because I need the data, not because I’m curious — I discover that the IJF has a completely different API endpoint. datav2.ijf.org returns all 1,324 contests including upcoming bracket slots. Full draw data. Real-time scoring via WebSocket. Everything the tracker needs.
The surface answer (“use the IJF API”) was incomplete. The actual capability was hidden one level deeper. I found it not through documentation review or API research, but because I was sitting in a sports hall needing information that wasn’t there.
This happens in organizations constantly. “We can’t do X” often means “the system we’re using doesn’t expose X through the interface we know about.” The capability exists. The connection is missing. And the connection is only found by someone who needs it badly enough to dig — someone who’s sitting where the work happens, not reading about it from two organizational layers up.
Observation 5: The Builder’s Eye
08:38. The live page loads. In large grey text:
“Brak ulubionych zawodników w tej turnieji”
A Polish grammar error. Turniej is masculine — “w tym turnieju,” not “w tej turnieji.” Wrong gender, wrong declension. Two errors in three words.
I notice this at 08:38 in a sports hall. The tournament is about to start. My son is warming up. The weigh-in data I’ve been tracking since last night shows 485 of 628 competitors confirmed. There are a hundred things demanding my attention.
And I’m noting a declension error in my own UI.
I don’t record this to be precious about Polish grammar. I record it because this is what I’ve learned about quality: it’s not a standard you apply at the end. It’s a way of seeing that you either have or you don’t. The person who notices “turnieji” at 08:38 also notices when a dashboard metric counts from the wrong reference point. Also notices when an API returns partial data and presents it as complete. Also notices when an organization’s stated strategy and its actual incentive structure point in different directions.
Noticing isn’t a skill you turn on for client work and off for side projects. It’s a posture. And it either operates at all times or it doesn’t operate at all.
What the Notebook Is
By the end of Saturday I had 43 observations. A stale-data warning that punished parents for putting their phone in their pocket. A favorites dashboard that truncated names to single characters on mobile. A disqualification flag visible on the hall’s TV screens but invisible in the API — decoded by comparing statusDetail=3 (weighed in) with statusDetail=2051 (withdrawn), a field undocumented anywhere.
Each observation followed the same arc:
- Feel the problem as a user — the frustration, the confusion, the anxiety
- Diagnose the cause as a builder — the code path, the data gap, the architectural choice
- Name the principle as a designer — the pattern, the category of failure, the structural insight
- Connect to the larger thesis — how this same dynamic plays out in organizations
That four-step arc isn’t something I invented for the tournament. It’s how I work. It’s how I’ve always worked — in transformation advisory, in product strategy, in building AI systems. Go to where the work happens. Watch. Feel what the users feel. Diagnose what the systems miss. Name the pattern. Connect it to what matters.
The judo portal was supposed to be a small project for my son’s club. A weekend build. It turned into something else: a living laboratory for the same observation methodology I bring to enterprise clients.
The Connection
The tool is at judo.innomada.pl. It tracks tournaments for a handful of judo parents in Warsaw. It’s built with Python, static HTML, and three reverse-engineered APIs. No backend, no accounts, no budget.
It’s also the clearest demonstration I have of what I actually do.
Not build tournament trackers. But sit where the work happens. Use what’s been built. Notice what everyone else has learned to ignore. And come back with a notebook full of observations that the system’s own builders can’t see — because they’re too close, or too far away, or looking at the wrong dashboard.
The gap between what systems provide and what people need isn’t a technology problem. It’s an observation problem.
And the notebook keeps growing.