I started Ventute in December 2022 as a rough idea. For the first couple of years it was mostly sketches and throwaway code. Most of what exists today was built in the last year, and I built it alone.
Ventute is a business simulation platform. You run a company, make decisions, and the engine plays out what happens next. Simple enough, until you realise a simulation you cannot replay is a simulation you cannot debug or trust.
Events instead of state
Every action in Ventute is stored as an event. The state of a company is never saved directly. It is rebuilt by folding the event log from the beginning. Same events in, same state out.
The hard part is making that true every single time. Wall clock time, randomness, iteration order and floating point all love to break replay quietly. So the kernel treats each of them as something that has to be controlled, not trusted. The goal was replay that matches bit for bit, not just close enough.
Monte Carlo without the GIL
Forecasting means running a lot of possible futures. In pure Python the GIL turns that into a queue. I moved the hot loop into Rust and call it through PyO3, so the simulations run on real threads in parallel while the API stays in async Python with FastAPI. PostgreSQL (serverless on Neon) and Redis handle storage and caching.
Parallel code and determinism usually do not get along, so every run has to produce the same answer no matter which thread finishes first.
Pulled out as open source
Three patterns from Ventute turned out to be useful on their own, so I published them on GitHub under m4xkushnir. An event driven replay kernel, a deterministic AI guardrail, and a small PyO3 bridge between Rust and Python. They are deliberately small so they are easy to read.
I am curious how others handle determinism in their own systems, especially around floats and parallel work. If you have fought the same battle, I would love to hear how it went.
Top comments (0)