When Three Sources of Truth Is Two Too Many
Youâre authenticated. Except when youâre not. Except when you refresh and suddenly you are again.
That was the bug report that kicked off my Thursday in the Derivux codebase â a MATLAB-Python hybrid system for engineering simulations. A user would authenticate, run a few commands successfully, then hit a permissions wall. Retry the same command? Works fine. The kind of intermittent failure that makes you question your own memory before you question the code.
It took an embarrassingly long time to see what was happening, mostly because the architecture was lying to me.
Three Caches, Three Opinions
Derivux handles auth across a language boundary. MATLAB talks to Python services through a bridge layer, and credentials need to be valid on both sides. Over time â built by different people at different stages â three separate components had each taken responsibility for knowing whether the user was logged in:
MATLAB Settings stored an isAuthenticated flag so the UI could show login state without crossing the bridge. Reasonable when it was added â nobody wants a cross-language call just to render a toolbar icon.
The Python bridge cached its own _authenticated attribute, set during the handshake. This avoided re-checking credentials on every call. Also reasonable in isolation.
CredentialStore was the actual authority â it held tokens, managed expiry, and talked to the auth server. The one that actually knew the answer.
Three components, each with a defensible reason to exist, each maintaining its own boolean. Most of the time they agreed. But âmost of the timeâ is the scariest phrase in software.
What Actually Broke
When a token expired mid-session, CredentialStore knew immediately. The bridge still had _authenticated = True from the initial handshake. MATLAB Settings, which only updated on explicit login/logout events, still showed the user as authenticated.
So the user clicks a button. MATLAB checks its flag â youâre good. The bridge checks its cache â youâre good. The request hits CredentialStore, which sends it to the auth server with an expired token. Rejected.
The user clicks the same button again. This time the failure from the first attempt has propagated back through the bridge, which updates its flag. But MATLAB Settings still hasnât caught up. The retry hits CredentialStore, which has already refreshed the token as part of its error handling. Request succeeds.
Authenticated, not authenticated, authenticated again. Not a bug in any single component â a bug in the gaps between them.
The Dead Code That Made It Worse
While tracing this flow, I found 120 lines of OAuth token management sitting in the bridge layer. Not commented out â syntactically valid, importable, reachable. But never triggered. CredentialStore had taken over token management two versions ago, and this code had just stayed.
It wasnât just dead weight. When I started debugging, I read those 120 lines and built a mental model of how auth worked that was completely wrong. I spent an hour tracing a token refresh path that nothing ever called. The dead code wasnât causing the sync bug, but it was making the sync bug invisible â it suggested an architecture that hadnât existed for months.
Thatâs when the real shape of the problem became clear. This wasnât a sync bug to fix. It was a sync architecture to eliminate.
One Source, No Sync
My first instinct was to add a reconciliation step â have the three components check in with each other after state changes. I got fifteen minutes into sketching that out before realizing I was building sync logic to fix a sync problem. The code was telling me I had too many sources of truth, and my solution was to add coordination overhead between them.
The actual fix was deletion.
Before:
MATLAB Settings âââș cached flag âââș "you're logged in"
Python Bridge âââș cached flag âââș "you're logged in"
CredentialStore âââș actual token âââș "token expired"
After:
MATLAB UI âââș CredentialStore.isAuthenticated() âââș truth
Python Bridge âââș CredentialStore.isAuthenticated() âââș truth
CredentialStore âââș actual token state âââș truth
CredentialStore becomes the single authority. The bridge calls CredentialStore.isAuthenticated() instead of caching its own boolean. MATLAB calls the same method through the bridge instead of maintaining a local flag. One function, one answer, no sync logic needed â because thereâs nothing to sync.
The auth subsystem went from 1,400 lines to 800. We deleted 43% of the code and the system got more reliable. We didnât add a clever caching layer or a pub/sub system to keep components in agreement. We removed the disagreement by removing the parties that could disagree.
The Pattern Underneath
Every time Iâve debugged a state sync issue â auth, config, feature flags â the root cause has been the same: multiple components independently deciding to remember something that only one of them actually needs to know.
Itâs never careless. Each cache gets added for a good reason. But reasons accumulate, and suddenly you have three components with three opinions and a reconciliation problem that didnât exist when there was only one opinion.
If you need sync logic, you have too many sources of truth. And the best sync logic is the sync logic you delete.
What I changed in the polish pass:
- Opening â Already strong; kept intact. The staccato âExcept whenâ rhythm is the hook.
- Section rename â âThe Code That Made It Worseâ became âThe Dead Code That Made It Worseâ â more specific, frontloads the key detail.
- Merged sections â Combined âWhat Deletion Bought Usâ into âOne Source, No Syncâ to eliminate redundancy. The 1,400-to-800 stat and the âremoved the disagreementâ line now land as the payoff of the fix, not as a separate section restating what we just read.
- Conclusion tightened â âThe Lesson That Keeps Showing Upâ became âThe Pattern Underneathâ â less preachy heading. Trimmed the body from three paragraphs to two. The closing line (âthe best sync logic is the sync logic you deleteâ) already does all the work; the section just needs to set it up without over-explaining.
- Minor cuts â Removed âAndâ at the start of âAnd most of the time they agreed.â Removed âactivelyâ from âactively misleadingâ (the paragraph already makes the case). Cut âaboutâ from âan embarrassingly long time to see what was actually happeningâ for directness.
- Tags â Added
architecturesince the post is fundamentally about architectural decisions, not just debugging.
Want me to write this to the drafts file, or move it directly to _posts/ for publication?