Come work with me on Hegel

As some of you may know, I decided that the logical step after writing Hypothesis was to join Antithesis, and once here I pitched them on the idea that we should create an open source property-based testing library called Hegel.

What you may not know is that we’re hiring engineers in London to come work on Hegel with me. Or, at least, we’re trying. We’re struggling a bit with sourcing at the moment, which seems crazy to me because this is, to my mind, a dream job. I’m admittedly a little bit biased in the shape of my dreams, but if you’re reading this blog maybe you are biased in the same way, so I thought I’d attempt to sell you on this in a less formal context than a job listing.

Here’s the short version: Would you like to do cutting edge research in software testing, in an open source project, with solid resources behind you, for a competitive tech company salary?

If the answer is no… I guess you and I are really not the same, because from my perspective this is very much what I’ve wanted to do for years and have never really properly got the opportunity to do before now, and it’s by far the best job I’ve had to date. It would be even better with another person or two on the project. Maybe that’s you.

Let me tell you a little bit more about it.

Some quick caveats

Here are the two things most likely to put you off applying for this job:

  1. Yes, it really is an in-person job in London, five days a week, and there isn’t a lot of flexibility on this. Antithesis is extremely keen on in-person work. I’m not going to try to defend this to you - personally I’d much rather a more hybrid policy, and this is probably the only job in the world good enough that I’d put up with my current commute for it - but if it’s a dealbreaker for you then sorry.
  2. We use Claude Code a lot on Hegel. We do so in a way that I am pretty confident leads to high quality results, but we do use it. You don’t have to be a Claude Code expert, or even to have used it at all, and its use is not literally mandatory, but it is strongly encouraged and you do have to be willing to work with us while we use it.

Sorry if that put you off immediately, but better that you find out now rather than later. Now let me tell you all the things that are great about it.

What’s Hegel?

Hypothesis-style property-based testing for every language. Or, at least, every language that someone is willing to do a small amount of design and ongoing maintenance work for. We currently support Rust, Go, Java, TypeScript, OCaml, and C++, and there are a variety of community supported languages as well.

The key idea of Hegel is that because Hypothesis-style property-based testing has an underlying unified representation and never needs to inspect generated values, we can move all of the engine into a single library written in Rust that we then expose via an FFI. Client libraries can then bind to that, and now everyone gets a high quality property-based testing library for their language.

On top of that, we’re not just trying to hit parity with Hypothesis, but to improve upon it.

For starters, the Hegel API is a bit different from Hypothesis, because we got to design it from scratch. Here’s the code we use as our standard example:

use hegel::generators as gs;
use hegel::TestCase;

#[hegel::test]
fn test_respects_lru_capacity(tc: TestCase) {
    let capacity = tc.draw(gs::integers::<usize>().min_value(0));
    let mut cache = MyLRUCache::<String, i64>::new(capacity);

    let entries = tc.draw(
        gs::vecs(gs::tuples!(gs::text(), gs::integers::<i64>()))
    );
    for (key, value) in entries {
        cache.put(key, value);
    }

    assert!(cache.size() <= capacity);
}

Unlike Hypothesis, which takes all of its generators up front in @given, Hegel’s draws are all inline in the test. This has always been possible in Hypothesis using st.data() but isn’t commonly used. I think this style leads to a much more flexible way of writing tests, so I’ve wanted to push it for a while, and conveniently it’s also a much easier style to make work across a variety of languages. A perk of getting to design the API from scratch is that we get to redesign it with the benefit of hindsight.

As well as the benefit of hindsight on the design, we’ve just got resources that I never had when implementing Hypothesis. Money, a team, and colleagues who can provide support and high quality feedback. Coding agents that are allowing us to e.g. build benchmarks, and large suites of tests that we can use to study the library. It all makes such a huge difference, to the point where I’m slightly sad that all open source projects don’t get to experience this.

On top of that, we’ve got a slightly different focus from the needs of Antithesis, which means we’re pushing the design space in interesting ways. Hegel is designed for larger test cases, with support for multithreaded tests, including concurrent stateful testing, and we’re focusing a lot more on power-user features.

If this all sounds neat, even if you’re not going to apply for the job, I recommend checking it out for your code. We’ve got implementations for Rust, Go, TypeScript, Java, OCaml, and C++. Some of these are better than others, but they’re all pretty good. If you don’t see your favourite language on the list, consider writing your own frontend. Hegel is still zerover and we’re breaking the C ABI a lot right now, so your experience keeping it up to date might be a bit rough, but it’s pretty doable.

Why open source?

One of the great things about Hegel as an open source project at Antithesis is just how well it being open source works for the company for purely selfish reasons. We’re currently in an era where big corporations are dropping a lot of their open source teams, but I think there is relatively little danger of that happening to Hegel because from a commercial point of view it being open source is the point. It couldn’t do what it does for Antithesis without that.

I describe the Hegel strategy for Antithesis as having roughly three prongs:

  1. The heart of our product is a deterministic distributed systems fuzzer, but the thing that makes that useful is that you can do property-based testing on it. The more people who know what property-based testing is and are enthusiastic users of it, the larger our market.
  2. In particular, if you’re an existing Hegel user, we can potentially offer a fairly one-click way of getting more out of your tests than you get locally, which gives us a very easy customer base.
  3. In order to use Antithesis, you need to write workloads - ways of exercising your system. By making Hegel one of the best tools for writing workloads available, we make the user experience of our product better. Hegel being open source doesn’t harm this use case at all, and makes it much easier for people to learn to use it well because they can try it outside of Antithesis, and because it increases the community and resources around it.

(There’s also a fourth prong which is that we’re heavy and enthusiastic users of it internally. This one isn’t as obviously benefited by it being open source, but it’s not hurt either.)

Why might you want to run your Hegel tests on Antithesis? Well, if you’re fuzzing a distributed system, which is Antithesis’s bread and butter, it’s more like you want to use Hegel to help you use Antithesis - this is the sort of workload which is an absolute nightmare in normal testing, but works great if you’ve got a fully deterministic environment to run it in, and the better your tools for expressing operations against that system the better you will be at finding bugs in it. This is case (3) from the above.

But even with very normal Hegel tests, Antithesis has a big advantage, which is long-running fuzzing. The sort of purely random testing you do in a property-based testing library like Hegel (or QuickCheck or Hypothesis, or most of the others) has a real problem: Because its drawn test cases are independent, if you’ve not seen a bug in your first N test executions, you should expect not to see one in the next N either. The result is that the value of running your tests more is logarithmic in how long you run them for - each time you double your testing budget, you should expect to find at most one more bug. In contrast, a well designed fuzzing process keeps adding utility for much longer, and so running Hegel under the Antithesis fuzzer buys you a lot of bug finding power.

All of this is a bit of a work in progress. Right now we’ve got a number of very enthusiastic Hegel users, many of whom are also enthusiastic Antithesis users, but we’re still working on getting enthusiastic Hegel-on-Antithesis users. The two work together, but not currently without some friction, which is one of the things we’re working on at the moment (and want more engineers to help us fix).

What would you be working on?

There’s a huge amount to do and a reasonable amount of individual latitude to pick among it, so to some degree this depends on who you are and what your interests are, but roughly there are three big streams of work:

  1. General purpose “make Hegel better” work. This might be ergonomics and user experience (e.g. I’ve been doing work on printing and settings recently. These are both surprisingly hard technical problems), API design, technical implementation details (e.g. we’ve been working on shrinking quality and the best distribution of floats for finding bugs).
  2. Hegel on Antithesis - this is the part of the work that is most focused on the core Antithesis product. It involves a mix of just using Hegel on Antithesis and finding the rough edges, and working with the fuzzer and product teams to try to figure out how best to integrate the two.
  3. Concurrent property-based testing: This is our current most active area where we’re having to figure out genuinely new design space in property-based testing. We’ve recently expanded our stateful testing to support concurrent execution of rules, and I’ve got an active research project on dealing with nondeterminism in property-based tests. We also expect this is an area where we’re going to have to figure out ways of expressing properties better - for example, we likely want to add in the ability to express Jepsen-style linearizability checking at some point, and that design space is wide open.

All of these are things we need more people on, so if any of them sound particularly exciting to you, there’s probably an opportunity for you to work on that.

In general, Hegel involves a lot of my favourite thing: Starting from real world problems experienced by users, finding the underlying technical tools we need to solve those, and doing hard research and engineering to achieve that.

Should you apply?

If the above sounds exciting, yes.

There are specific things that are nice-to-haves: Experience with property-based testing, Rust, open source, etc. These are all important, but really if we think you’re a great engineer any you want to work on the sorts of problems I’m describing here, you should apply.

You can apply via the official job posting, but if you’re unsure about applying or otherwise have questions, feel free to email me on my work email at david.maciver@antithesis.com, or any other way you’ve got to contact me.

NB: While I am happy to answer questions, I cannot process job applications, you’ll have to apply through the job posting. Also, we are not currently working with new external recruiters at this time, so please don’t bother contacting me if you’re a recruiter as I wouldn’t be able to help you even if I wanted to.


  1. Or, really, libraries. The point of Hegel is that it can support many languages, so each language gets a library, binding to one core library.

    ↩︎
  2. It’s on the job posting, but just to repeat it here, the listing for the job is £140k-175k, which is on the high side for a startup in London.

    ↩︎
  3. There is some in that it’s not literally mandatory to be in the office every day and people can and do work from home on days they need to, but the expectation is five days a week in the office with exceptions when you need them.

    ↩︎
  4. Me especially.

    ↩︎
  5. Claude Fable can do a pretty good one-shot of a Hegel frontend these days. You’ll definitely want to tweak the results for usability before publishing it though. I’d rate the vibecoded versions as good enough to use, but maybe not good enough to want to put your name to in public.

    ↩︎
  6. Strategies in Hypothesis

    ↩︎
  7. And probably make brand new mistakes.

    ↩︎
  8. I mean obviously the reason we want it to be open source is not purely selfish. I love open source software. But it’s great to have a robust backing for it.

    ↩︎
  9. Technically they’re only mostly independent, but there’s not enough dependency to solve the problem.

    ↩︎
  10. This is the one area where the interests of Hegel the open source library and the interests of Antithesis are not 100% perfectly aligned, which is that we’re not especially incentivised to work on long running fuzzing in the open source Hegel. We do vaguely intend to provide a libfuzzer backend for Hegel at some point so that other people can do the fuzzing work, but most of our data generation work is going to be focused on letting it find medium-depth bugs fast rather than the heavy duty exploration you can get in Antithesis. Fortunately there’s sufficiently many important and interesting things to work on that I don’t think this is a huge problem, and the failure mode is that we’re no better than all the other property-based testing libraries in the world.

    ↩︎
  11. It may seem weird that randomised testing needs specific handling of randomness, but the problem is that this is randomness that is not under our control because e.g. it comes from the thread scheduler.

    ↩︎