Founder Notes
Storage Is Not Provenance

There is a category of system that looks finished long before it is useful, and I have spent the last stretch of my career building one.
The observation is simple enough to state in a sentence: storing evidence and proving provenance are completely different engineering problems. Almost every product I have looked at in this space solves the first and quietly presents it as the second.
The problem that is already solved
The storage problem is: accept a file, keep it safe, get it back on request.
This is genuinely solved. It is a bucket with an access policy, some lifecycle rules, and a retrieval path. You can build it in a week, it demos beautifully, and every part of it is a well-trodden path with good libraries.
It is also, on its own, almost worthless for the thing users actually need.
The problem that is not
The provenance problem is: given this specific physical object, produce the document that describes this object, and be able to show why the two are connected.
That is not storage. That is an identity graph, and the edges in it are assertions you have to be prepared to defend to someone standing in front of you asking about a specific item.
The difference becomes obvious the moment you write the query. Storage answers where is the file. Provenance answers which file is about this thing, and the second question has a join in it.
The join is where everything fails
I expected the hard part to be scale, or search, or schema design. It was none of those. The hard part is that the join depends on data you do not control, entered by people who had no idea it would later be load-bearing.
The failures are relentlessly boring:
- A supplier recorded an identifier one way on the invoice and another way on the label.
- A laboratory reported a sample ID that maps to a batch rather than to the unit you care about.
- Someone repacked a case in the back, correctly and helpfully, and severed the link.
- Two deliveries of the same item arrived within a day of each other and were shelved as one.
Not one of these is a mistake in any meaningful sense. Each of them breaks the connection between the paper and the thing.
The fuzzy-matching trap
The engineering instinct here is strong and completely wrong. You have two records that nearly agree. Same supplier, same week, one character different in an identifier. Obviously the same thing. Match them.
I understand the instinct because I had it. It is wrong because of what the output of this system is for.
A recommendation engine that guesses is fine — a bad guess costs a slightly worse suggestion. An evidence system that guesses produces a confident answer with nothing behind it, and hands it to someone who is going to rely on it in a setting where being wrong is expensive.
A probabilistic join in an evidence system is worse than no answer at all, because no answer prompts a human to go and look.
Making mismatch a first-class state
What worked was giving disagreement somewhere to live.
Not an exception. Not a log line. Not a nullable field that downstream code treats as absence. An explicit state that says: these two records are supposed to describe the same thing, they do not agree, here is precisely how they differ, and a person decides.
This is slower and dramatically less magical. Users do not thank you for it. But it means the system's confident answers are actually confident, and its uncertain answers are visibly uncertain — which is the only property that matters when the output is intended to be relied upon.
The generalisation
I think this applies well beyond compliance, to any system whose output is meant to function as proof.
Ask what your system does when two sources of truth disagree. If the answer is "picks one", or "picks the most recent", or "merges them", then you have a system that manufactures certainty. It will do this silently, at scale, and everyone downstream will believe it — because from the outside a manufactured answer and a real one look identical.
The bucket is the easy part. It was never the product.