Every large organization has the same quiet problem: the best information about risk doesn't live in a database. It lives in Slack threads, hallway conversations, and the "gut feeling" of a regional expert who's watched a particular market or regulatory environment for years. That judgment is valuable, but it's almost never quantified, almost never checked against reality, and almost never connected to an auditable trail of action.
I've watched this play out from the outside, too. A risk committee gets a slide that says "our regional lead is concerned about currency exposure in this market," and that's it. No number, no history of whether that lead has been right before, no comparison to what the actual market is pricing in. The concern might be completely justified. It might also be recency bias from one bad quarter. Nobody in the room has a good way to tell the difference, so the decision either gets made on vibes or gets deferred until it's too late to act cheaply.
I wanted to build something that closes that gap: a tool that forces expert intuition into a number, benchmarks that number against real market data, and keeps a governed record of what happened next. That's how Northbridge Analytics was born, a decision-support platform aimed at CFOs and Chief Risk Officers who need more than anecdotes when they're deciding whether to hedge exposure.
The core idea
Northbridge is built around one simple tension: internal belief vs. external reality.
- ICP (Internal Consensus Probability), a weighted probability derived from what your own regional experts believe will happen.
- EMP (External Market Probability), the real-time signal coming from prediction markets and financial data.
When those two numbers drift apart, that's a blind spot. Someone inside the organization either knows something the market doesn't, or the organization is dangerously out of touch. Either way, it's worth surfacing, and Northbridge's Divergence Engine does exactly that, flagging significant gaps so they can be reviewed before they become expensive.
I spent a lot of time thinking about what "significant" should mean here. A naive version of this feature would just subtract ICP from EMP and flag anything over some fixed threshold, like ten percentage points. But a ten-point gap on a coin-flip event isn't the same as a ten-point gap on something the market already prices as a near-certainty. So the divergence calculation has to account for where the two numbers sit on the probability curve, not just the raw distance between them. Getting that math right, so that the flags actually correspond to decisions worth making instead of noise, took several iterations.
To make the internal side trustworthy over time, I added reputation weighting based on Brier Skill Scores, so experts who are consistently accurate carry more influence in the consensus than those who are just loud or senior. Calibration, not politics, should decide whose forecast matters most. This part mattered a lot to me personally. Anyone who has sat in a room where the most confident person automatically wins the argument knows how badly that can go. A system that quietly tracks who has actually been right, and lets that history shape influence over time, is a small structural nudge toward better decisions. It doesn't eliminate politics, but it makes the politics have to argue with a track record.
Architecture decisions
I built the client as a native Kotlin Android app, following an MVVM pattern with StateFlow for reactive, lifecycle-aware state management. A few decisions I made early on, and why:
Offline-first with Room. Regional experts don't always have reliable connectivity, whether that's someone traveling, working from a site with poor infrastructure, or just being on a flight when a market moves. Local persistence via Room, which sits on top of SQLite, had to be the source of truth on-device, syncing to the backend when possible. This meant designing the local schema first and treating the network as an enhancement rather than a dependency, which is the opposite of how a lot of apps are built by default.
Retrofit and MySQL as the "Global Ledger." The backend needed to act as a single, centralized record. Every forecast, review, and hedge approval writes to an audit log that can't quietly disappear. I used Retrofit to handle the HTTP layer cleanly and kept the API contracts strict, since a governance tool is only as trustworthy as its ability to prove that nothing has been altered after the fact.
Repository pattern. A RiskRepository sits between the UI and both the local Room database and the remote API, handling sync logic and running the divergence calculations before pushing results back into state. Keeping this logic out of the ViewModels made the sync behavior much easier to reason about and test in isolation, and it meant the UI layer never had to know or care whether a given probability came from the cache or from a fresh network call.
Governed workflows over free-for-all inputs. Once a probability estimate is submitted, it's immutable. If a hedge gets approved, that's logged too. The whole point is an audit trail a risk committee can actually trust. This constraint shaped the database design from day one. Instead of allowing updates to existing rows, corrections and revisions are stored as new entries that reference the original, so the full history of how a belief evolved is always visible rather than overwritten.
Putting it together, the pipeline looks roughly like this: an expert submits a quantified estimate, the app recalculates the weighted internal consensus, the Divergence Engine compares it to the external market signal, and if the gap crosses a threshold, it flags the CFO or CRO for review. An approved hedge gets committed to the ledger, and the whole thing can be exported as a PDF for the board. Every step in that chain is designed to leave a trace, so that six months later someone can reconstruct exactly what was known, by whom, and when.
What I learned
The hardest part wasn't the Kotlin or the sync logic. It was designing for governance rather than just functionality. It's easy to build a form that captures a probability. It's harder to build a system where that probability can never be quietly edited after the fact, where every state transition is logged, and where the audit trail is actually useful to a risk committee months later. That constraint shaped almost every technical decision, from making estimates immutable at the database layer to structuring the role-based access control around who's even allowed to resolve an event.
I also learned how much thought has to go into role design before a single screen gets built. Deciding who can submit a forecast, who can review a divergence flag, and who has the authority to approve a hedge is not a UI problem, it's an organizational modeling problem. I ended up sketching out the actual approval chain of a hypothetical CFO's office on paper before writing any permission logic, because getting that model wrong would mean rebuilding a lot of the backend later.
Another lesson was around how to present uncertainty without letting the interface lie by omission. It would have been easy to just show a single blended probability number on the main screen and call it a day. But a single number hides disagreement. If three experts are clustered tightly around 30% and two are convinced it's 70%, that's a very different situation from five experts who all independently landed on 45%, even though the weighted average might look similar. So the UI needed to expose the spread of opinion, not just the summary statistic, which pushed me to think more carefully about how to visualize distributions on a small mobile screen without overwhelming the user.
What's next
There's plenty on the roadmap. I want to build deeper reporting around "value protected" metrics, so a CFO can see not just that a hedge was approved but what it likely saved the organization in expected terms. I'm also interested in more sophisticated calibration across multiple event cycles, since Brier scores get more meaningful the more forecasting history an expert accumulates, and right now the reputation system is still working with a fairly thin data set. Beyond that, I'd like to extend the client past Android, since a lot of the value of Northbridge only compounds if more of an organization's experts can easily contribute a forecast from whatever device they happen to be using.
But even in its current state, Northbridge does the one thing I set out to do. It turns scattered judgment into a number, and it turns that number into something governed.
If you're curious about the code, architecture diagrams, or want to run it locally, the full project is open source here:
Top comments (0)