This closes out a run of posts about rewriting my own production infrastructure as a commercial app, one Mac build in Swift, one Windows build in C#, sharing no code between them by design. I wrote about that decision at the start of this series, and I said I'd come back once the shared contracts holding the two apps together had actually caught something. They have. This is that.
The shape of the contract, briefly
Two engines, one on each platform, idiomatic to each, means nothing enforces agreement between them automatically the way a shared core would. What replaces that automatic agreement is a small set of artifacts both apps have to answer to independently: one JSON Schema the configuration document on both platforms has to validate against, a shared database schema for the local stores, and golden fixture files, concrete input-and-expected-output pairs for cron expressions, daylight-saving transitions, and configuration round-trips, that both test suites run against and both have to pass. Neither app reads the other's source. Both apps have to agree with the same file. I laid out the reasoning for that split, and the alternative I rejected, in rewriting my own infrastructure as a product.
What the fixtures are actually for
A shared fixture file only does its job if both implementations are actually pinned against it, run in each platform's own test suite, not just present in the repository as a document nobody executes against. The Mac side built its own DST fixtures early and used them directly, which is how I found the three daylight-saving bugs I wrote about in what broke when I wrote my own scheduler. What I hadn't done yet, at the time I wrote that post, was pin the Mac's cron evaluator against the same shared cron-fixtures.json file the Windows side already runs its own evaluator against. The Mac evaluator had its own inline test cases, written independently, and passing. Independently passing tests on both platforms sounds like parity. It isn't, not until both are checked against the identical set of cases, because independently-written tests share the blind spots of whoever wrote them, on each side, separately.
The bug that only a shared fixture could have caught
Once I went to actually wire the Mac evaluator against the shared cron fixtures, one case exposed a real divergence: the expression 0 0 12 * * MON, noon every Monday, with the day-of-month field left as a wildcard and the day-of-week field constrained. Quartz's own documented rule for this exact ambiguity, a wildcarded day-of-month combined with a constrained day-of-week, is that the constrained field wins: fire only on Mondays. The Windows evaluator, built independently against the same documented rule, gets this right. The Mac evaluator, also built independently, ORs the two fields together instead: a wildcard day-of-month matches every day regardless, so a job meant to fire once a week was firing every single day, silently, on the Mac build only.
This is precisely the failure mode the whole two-engines-one-contract design exists to catch, and it worked exactly as intended. Two independent implementations of the same specification, each internally consistent, each passing its own hand-written tests, quietly disagreed with each other on a real, specific, dated cron expression. Neither test suite alone would ever have surfaced that; each was only ever checking itself against its own author's understanding of the rule. The shared fixture, the same file, the same expected answer, checked by both, is what turned a silent, per-platform behavioral bug into a loud, specific, immediately actionable test failure the moment the Mac side actually ran against it.
What's still open, honestly
Parity is a discipline you keep practicing, not a state you reach once. A few gaps are still sitting in the backlog as of this post, and naming them here is more useful than pretending the contract is airtight. The config document's date fields are one: the Mac side currently encodes certain timestamps as raw reference-date numbers, while the shared schema specifies ISO 8601 and the Windows side already writes it that way, which means a config file written by one platform doesn't yet round-trip cleanly if opened by the other. There's a wake-on-enqueue behavior, a newly arrived scheduled item getting picked up immediately rather than waiting for a fallback poll, that Windows wires explicitly and Mac needs to confirm it has an equivalent of. And there's a stored-but-unenforced config field, a scheduler job's "only run if this folder has files in it" gate, present and editable on both platforms and acted on by neither, an explicit decision still waiting to be made rather than a bug.
None of those are hidden. They're written down in the same place the cron divergence was written down before it got fixed, which is the entire point of keeping the list at all. A parity gap you've named is a task. A parity gap you haven't looked for is a bug two platforms are quietly disagreeing about right now, the same way the Monday cron case was for however long it went unpinned.
What this series was actually about
I develop the Windows side of this from the same Mac I develop the Mac side on, editing over a mounted volume and building over SSH into a VM, a setup I wrote about separately in one repo, two machines. That logistics story and this contracts story are two different answers to the same underlying fact: building two real, independent, idiomatic implementations of one product is more work than building one shared core, and every piece of extra discipline, a mounted share, a shared schema, a fixture file both sides actually run, exists to buy back the parity a shared core would have given away for free.
It's buying that back for real, not in theory. A shared core would have made the Monday cron bug structurally impossible, because there would only be one implementation to be wrong. Two engines made it possible, and a shared fixture, actually run on both sides, made it visible before either app had shipped it to anyone. That's the trade this series has been about since the first post: not eliminating the risk of divergence, but making sure divergence fails loud, specific, and early, instead of quiet and expensive. The build continues past this post. The contract is what makes it safe to keep building two of it at once.