There are two functions you will not find anywhere inside the simulation engine of techdiagrams.net: Date.now() and Math.random(). Not discouraged — banned. A pull request that introduces either is wrong by definition, no discussion needed.
That sounds dogmatic until you see what the ban buys.
What the engine does
techdiagrams.net lets you draw an architecture and then execute it: declare the promises your business depends on ("never charge a customer twice", "no order is lost"), and the engine derives the failure scenarios that could break them — crashes between steps, timeouts that secretly succeeded, duplicate deliveries, messages lost in transit — and runs your design through every one of them.
When it finds a violation, it doesn't hand you a probability. It hands you a trace:
t=140ms charge:payment (attempt 1)
t=141ms crash — API dies after commit, before response
t=380ms charge:payment (attempt 2) ← retry, not idempotent
VIOLATION: no-double-chargeThat trace is only worth something if it's reproducible. Which brings us to the ban.
Determinism is a feature, not a style preference
Every simulation run is a pure function of three inputs:
(document, scenario, seed) → identical output, every time, on every machineTime inside the engine is a virtual clock — an integer that advances only when the event queue says so. Randomness is a seeded PRNG injected at the start of the run. Nothing else may influence execution order: events at the same virtual time break ties on a monotonic sequence number, never on wall-clock arrival or map iteration order.
One wall-clock read or one unseeded random and all of this collapses into "well, it failed on my machine." Here is what the discipline buys instead:
Replayable bug reports. A violation trace plus its seed is a perfect reproduction. Anyone can re-run the exact interleaving that broke the design — the same millisecond-by-millisecond story — on any machine, any day.
Regression tests for architectures. We commit golden replays: a fixed document, scenario and seed must produce a byte-identical metrics snapshot forever. If a refactor of the engine changes any behavior, a golden test fails before a user ever sees it. Your architecture's verdict cannot silently drift between releases.
Honest verdicts. The engine's findings are claims of fact: "under these declared semantics, this interleaving double-charges." A claim of fact you can't reproduce is an opinion. Determinism is what keeps the engine in the fact business — and it's why our AI features are walled off from it. Models advise; only the deterministic engine gets to say proven.
The implementation is smaller than the willpower
The mechanics are honestly unexciting — an event queue ordered by (virtualTime, sequenceNumber), a splitmix-style PRNG handed down through the call tree, timers modeled as messages the queue delivers. Maybe two hundred lines that any of us could write.
The hard part is the fence: every place the outside world wants to leak in. A cache that expires by real time. A library that shuffles with Math.random(). A well-meaning console.log with a timestamp that becomes load-bearing. The ban exists because determinism doesn't degrade gracefully — you either have all of it or none of it, and you usually discover which one you have three weeks after the leak.
So we made it a rule instead of a review comment: no wall clocks, no unseeded randomness, inside the engine, ever. Rules scale better than vigilance.
Try the payoff
Draw a checkout flow, declare "never charge twice", add a retry without idempotency, and press Verify. The engine will find the exact crash-and-retry interleaving that double-charges — and it will find the same one tomorrow, which is precisely the point.
techdiagrams.net is free, local-first, and runs in your browser. Break your architecture before production does.