One domain spec, two runtimes, one test suite
Standalone runs Dart. LAN and online run Java. Keeping them byte-identical is not a nice-to-have — it is the thing that makes switching deployment shapes safe.
A single-PC shop should not need a JVM. A ten-station distributor should not run its books through a desktop app. So Telos ships two implementations of the same rules: Dart for standalone, Java for LAN and online.
Two implementations of anything is a liability. Two implementations of money is a liability with a number attached.
The rule
A change to a domain rule ships in three places in the same pull request: the Dart implementation, the Java implementation, and a test vector.
A vector is a JSON file with inputs and the exact expected output. Both runtimes read the same file. CI runs both and fails the build on any mismatch — not "close enough", not "rounding difference". Byte-identical.
What this catches
The interesting failures are never the obvious ones.
- Rounding. Java
BigDecimalwithHALF_EVEN, Dartdecimalwrapped in our own money type. Two libraries agreeing on 2.5 rounding to 2 is not automatic. - FEFO ties. Two batches with the same expiry date. Which goes first? Whatever the vector says — and both runtimes had better say the same.
- Calendar edges. Solar Hijri leap years do not line up with Gregorian ones. A date that exists in one calendar and not the other is a vector.
What it costs
Every domain change is roughly twice the work, plus a vector. We think that is the right trade for a product where a customer can start on one PC and move to a server without their numbers changing underneath them.