BluuAlpha
Blog
AlphaTournamentsPractice

Store the facts, derive the rest

Most data that disagrees with itself was typed in twice. Decide which values are facts, enter those once, and compute everything else from them.


Watch a youth tournament run on a whiteboard, a spreadsheet, and a group text, and by the second afternoon the three disagree. A score got written on the board but not in the spreadsheet. Somebody updated the bracket by hand and moved the wrong team. Nobody lied; the same fact was simply entered in three places, by three people, at three different times.

Business systems fail the same way, just more quietly. A status column that no longer matches the events table. An order total stored next to line items that were edited after checkout. A dashboard number that one team trusts and another recomputes in a spreadsheet every Monday. The fix is the same in every case, and it is a design decision, not a cleanup project.

Every copy of a fact is a chance to disagree

When a value can be computed from other values and is stored anyway, the system now has two answers to the same question. They agree on the day it ships. After that, every bug, every manual fix, every import script that touches one and not the other pulls them apart. The disagreement is rarely loud. It shows up as a report that is slightly off, and a meeting spent working out which number is right.

So before building the screens, we sort the data into two piles. Facts are things that happened and that a person or an outside system tells you: a score, a payment received, a reading from a sensor, a decision someone signed. Everything else is derived: totals, rankings, statuses, eligibility, what happens next.

A test for which pile a value belongs in

  • If you deleted it, could you rebuild it from other data you keep? Then it is derived.
  • Does someone have to type it, or does it arrive from outside? Then it is a fact, and it should be entered exactly once, in one place.
  • When two values disagree, which one would you believe? That one is the fact. The other should never have been stored.

The test sounds obvious, and it still catches things. Teams routinely find a “status” field that people edit by hand while code also sets it, which means it is neither a fact nor reliably derived.

What it looks like in practice

We built AlphaTournaments around this line. Once the schedule is set, the only thing anyone enters is a final score. Standings, tiebreakers, seeds, and bracket advancement are all computed from the games actually played. Nobody types a standing, so there is no standing to mistype, and the bracket cannot contradict the results because the results are the only thing it is made from.

The same shape holds in work that has nothing to do with sports. An invoice status computed from payments received instead of a dropdown. A readiness flag computed from the checks that passed instead of a box someone ticks. It holds for AI features too: a model’s summary is derived data. Keep the inputs and the prompt version that produced it, and you can regenerate it or explain it later, which is most of what we argued in what to instrument on an AI feature.

When to store a derived value anyway

There are good reasons to keep a computed value. Some are expensive to compute on every read. Some need to be frozen: what the invoice said on the day it was sent is a fact in its own right, even if prices change later. That is fine, as long as the stored copy is labeled as a cache or a snapshot, has one piece of code that writes it, and can be rebuilt from the facts and compared. If you cannot rebuild it, it has quietly become a second source of truth.

The practical step is small. Pick one screen your team argues about and list every value on it as fact or derived. The derived values that are stored and edited by hand are where the next disagreement is coming from. That kind of review is a normal part of our delivery and platform work, and it is cheaper to do before the data is real than after.

Written by Tommy Shrove, BluuAlpha Technologies.

More from the blog

Have a project that needs this kind of thinking?

Two weeks to straight answers, or a pilot if you already know the answer.