Your best week ever was a duplicate event
Event contracts put your tracking plan in CI, where bugs die cheap

Introduction
The Tuesday deploy went out clean. By Thursday, signup conversion had doubled, and by Friday the number was on a board slide with the word "momentum" next to it. Marketing moved budget toward the channel that was suddenly performing. Two engineers got a shout-out in the all-hands.
The following sprint, someone noticed that the mobile app was firing the signup event twice: once from the new confirmation screen, once from the legacy callback nobody had deleted. Conversion had not doubled. Counting had.
The expensive part was not the bug. It was the three weeks of decisions made on top of it: the reallocated budget, the paused experiment on the "losing" channel, the hiring conversation that referenced a growth curve that did not exist. An analytics bug does not crash. It convinces. A broken API pages someone at 2am; a broken tracking event produces a smooth, plausible, wrong number that walks into your Monday meeting unchallenged.
The pipeline that accepts anything
Here is the structural reason this keeps happening. Your product's API has a contract: send a malformed request and it gets rejected, loudly, with a status code. Your analytics pipeline has the opposite disposition. Send it anything, anything at all, and it says thank you. Rename a property, fire an event twice, change a string to an integer, drop a field: every one of those lands in the warehouse as data, and every dashboard downstream absorbs it without a flicker.
The asymmetry is the whole problem. Application code fails at the point of the mistake. Instrumentation fails at the point of the decision, weeks later, in a meeting, wearing a suit of legitimate-looking charts. (By then the engineer who made the change has shipped four more releases and remembers nothing.)
The fix is to give instrumentation what application code has had for decades: a contract, enforced by a machine, at the moment of the change.
Treat every event like a public API
The method is called an event contract: a machine-checked schema for every event your product is allowed to emit. Teams that run it treat their tracking plan as versioned code, not as a spreadsheet of good intentions.
It works like this. Every event your product emits, signup_completed, checkout_started, plan_upgraded, is defined once, in a schema registry that lives in the codebase: name, properties, types, allowed values, owner. Code that emits an event is checked against that registry in CI, the same way a type checker verifies a function call. Emit an event that is not in the registry, or send a property with the wrong type, and the build fails before the change ships. Renaming a property is a schema migration with a version bump, not a silent divergence. And the registry drives a staging check: replay the critical flows, assert that exactly the expected events fired, exactly once.
We built this for a subscription platform whose funnel numbers had quietly disagreed with billing for months: forty-one events defined, every emit gated in CI, and a replay suite over the five money flows. The next duplicate-fire never reached the warehouse. It failed a pull request instead, at a cost of one red build and a two-line fix.
Quality moved from the dashboard, where it is archaeology, to the pull request, where it is a diff.
The honest counterargument is that contracts add friction, and shipping a new event now takes a schema entry plus a review. True. That friction is measured in minutes. The alternative was measured, in the case above, in a quarter of misdirected spend and a board slide that had to be walked back, which is a genre of meeting nobody requests twice.
The number a decision stands on
The test for whether you need this is one question: if your most-watched metric moved 15 percent tomorrow, would your first instinct be to trust it or to audit it? If the answer is audit, your dashboards are not instruments, they are rumors, and every decision standing on them inherits the doubt.
This is the kind of system TensorLabs builds: the unglamorous contract layer that makes the glamorous charts mean something. The dashboard was never the product. The confidence to act on it is.
You might also like
Keep reading from the journal.
July 8, 2026Data
Add a Zero-API-Key LLM Review Gate to GitHub Actions with VibeThinker-3B
On June 17, 2026, nine researchers at Sina Weibo released VibeThinker-3B: a 3.1-billion-parameter reasoning model, MIT-licensed, post-trained on Alibaba's Qwen2.5-Coder-3B.
July 6, 2026Engineering
Build a Screenshot-to-React Service with Kimi K2.7 Code HighSpeed
In late June 2026, Moonshot AI added a HighSpeed serving tier for Kimi K2.7 Code, the one-trillion-parameter open-weight coding model it published under a Modified MIT license on June 12.
July 6, 2026Agents
The delivery date is a promise your data has to keep
Compute the date from inventory, cutoffs, and carrier history