# .plan-26-24: Apparently a professor now; still debugging io_uring at midnight

*2026-06-14 — note*


Blimey, I got promoted to a full professor at Cambridge this week (glamorously known as [Grade 12](https://en.wikipedia.org/wiki/Academic_ranks_in_the_United_Kingdom#:~:text=Reformed%20academic%20rank%20structure%20of) in Cambridge parlance), and had it [announced in the Cambridge Reporter](https://www.admin.cam.ac.uk/reporter/2025-26/weekly/6828/6828.pdf)! My first thought when I got the news was how much _fun_ this job has been over the years! As a kid, I always wanted to be a bus conductor (a job that increasingly no longer exists)...

<a href="https://www.admin.cam.ac.uk/reporter/2025-26/weekly/6828/6828.pdf"> <figure class="image-center"><img src="/images/reporter-261.webp" alt="In week 6828 of Cambridge University's existence did I get bumped up the pecking order a bit" title="In week 6828 of Cambridge University's existence did I get bumped up the pecking order a bit" loading="lazy" srcset="/images/reporter-261.768.webp 768w, /images/reporter-261.640.webp 640w, /images/reporter-261.480.webp 480w, /images/reporter-261.320.webp 320w, /images/reporter-261.1600.webp 1600w, /images/reporter-261.1440.webp 1440w, /images/reporter-261.1280.webp 1280w, /images/reporter-261.1024.webp 1024w"><figcaption>In week 6828 of Cambridge University's existence did I get bumped up the pecking order a bit</figcaption></figure> </a>

I have nothing but gratitude to my community that has made this all so much fun. A quick count across my papers shows 295 coauthors across 142 papers, but the vast majority of this diversity has been since I pivoted with [Srinivasan Keshav](https://svr-sk818-web.cl.cam.ac.uk/keshav/wiki/index.php/Main_Page) to environmental science back in 2021. Getting promoted wasn't a sure thing at all after I did that, since it's a bit odd from a CV perspective to flit between subjects mid-career.

Luckily (aside from never actually caring about having a conventional 'career'), I've had incredible senior academic mentors support me. [Jon Crowcroft](mailto:jon.crowcroft@cl.cam.ac.uk) takes the lead with a remarkable instinct that usually makes him eventually correct but never at the expense of joy, my officemate [Simon Peyton Jones](https://simon.peytonjones.org/) has endless enthusiasm for encouraging me to follow my instincts and not just keep doing the same thing; and several formative chats with [Phillipa Gardner](https://www.doc.ic.ac.uk/~pg/) where she connected the dots between computer/conservation science just enough to make me feel like I wasn't diving entirely into the unknown.

<figure class="image-center"><img src="/images/crowcroft-mill-celeb.webp" alt="My academic career started at the Castle with Crowcroft, and it endures down at the Mill with Crowcroft." title="My academic career started at the Castle with Crowcroft, and it endures down at the Mill with Crowcroft." loading="lazy" srcset="/images/crowcroft-mill-celeb.768.webp 768w, /images/crowcroft-mill-celeb.640.webp 640w, /images/crowcroft-mill-celeb.480.webp 480w, /images/crowcroft-mill-celeb.3840.webp 3840w, /images/crowcroft-mill-celeb.320.webp 320w, /images/crowcroft-mill-celeb.2560.webp 2560w, /images/crowcroft-mill-celeb.1920.webp 1920w, /images/crowcroft-mill-celeb.1600.webp 1600w, /images/crowcroft-mill-celeb.1440.webp 1440w, /images/crowcroft-mill-celeb.1280.webp 1280w, /images/crowcroft-mill-celeb.1024.webp 1024w"><figcaption>My academic career started at the Castle with Crowcroft, and it endures down at the Mill with Crowcroft.</figcaption></figure>

My top accolade, of course, is to all the wonderful students that make the
academic job a perpetually dynamic and engaging one. Pembroke College has been
a wonderful home from which to explore academia alongside my department. I
can't imagine being in a University that doesn't have the College/department
split like we do here, as it ensures we're exposed to a barrage of diverse
ideas from different fields all the time.

But anyway, onto more pragmatic matters: [Tessera v1.1 is out](#tessera-v11-released) and I've been [refreshing io\_uring and Eio](#more-io-uring-and-eio-work) to move all its data around; I got [cut off from Fable](#going-hyper-local-with-in-process-llms) and went local with a DeepSeek library; got [self-hosted email feedback](#self-hosted-email-feedback-and-dkim2); and [a never-ending review pile and usual fun links](#fun-and-not-fun-links).

## Tessera v1.1 released

We [released TESSERA v1.1](https://anil.recoil.org/notes/tessera-v11-out) this week as a retrained, drop-in successor to [v1.0](https://anil.recoil.org/papers/2025-tessera). Downstream code just points at new embedding tiles and should see its accuracy tick up for free, and the headline improvements are fewer artefacts in low-observation areas (v1.0 used to show grid-like seams where Sentinel-1 ascending/descending coverage met and one side had three times the valid observations of the other; this still exists in some regions of the world but is much better in v1.1); better year-on-year temporal stability which makes change detection and cross-year classifier transfer work better; and an expanded 20km coastal buffer that finally brings small islands and coastlines into coverage.

Read the [details](https://anil.recoil.org/notes/tessera-v11-out) elsewhere; we're now generating embeddings for two model variants and so I've updated the [live coverage map](https://ucam-eo.github.io/tessera-coverage-map/) to track v1.0 and v1.1 side-by-side so you can see exactly which tiles exist for each year:

<div class="video-center"><iframe title="The live coverage map now tracks both v1.0 and v1.1 tiles, updated by a GitHub Action" width="100%" height="315px" src="https://crank.recoil.org/videos/embed/97d422a2-af9c-47b5-947a-c136ad7093b6" frameborder="0" allowfullscreen sandbox="allow-same-origin allow-scripts allow-popups allow-forms"></iframe></div>

Going global with multiple models has surfaced its own crop of artefacts as we can now compare generations, but they're markedly less severe and we're continuing to grind them out. I released [geotessera 0.9](https://github.com/ucam-eo/geotessera/releases/tag/v0.9.0) and also uploaded the model weights to [Hugging Face](https://huggingface.co/geotessera/TESSERA-V-1.1), all under CC0.

### More io-uring and Eio work

Moving all those embeddings around at scale is a lot of bulk I/O, which gave me the perfect excuse to keep hacking on the [ocaml-uring](https://anil.recoil.org/notes/2026w23) I started last week. [Thomas Leonard](https://github.com/https://roscidus.com) is [hacking away on Eio](https://notes.roscidus.com/2026/06/12/) alongside me and [Patrick Ferris](https://patrick.sirref.org) so this is a good time to get the feature queue into shape. Most is unglamorous plumbing unless you're into [surfing Linux syscall tables](https://filippo.io/linux-syscall-table/), but it's the good kind:

- [PR \#151](https://github.com/ocaml-multicore/ocaml-uring/pull/151) lets us set `CLOEXEC` when uring creates a socket, so [eio\#843](https://github.com/ocaml-multicore/eio/pull/843) can move that path fully onto uring rather than dropping back to a plain syscall. Close-on-exec is a weird default in the modern world, so [always setting it](https://github.com/rust-lang/rust/issues/24237) is a good idea.
- [PR \#154](https://github.com/ocaml-multicore/ocaml-uring/pull/154) threads per-operation `preadv2`/`pwritev2` flags through the submission path. I was rooting around in liburing and noticed that `RWF_DSYNC` lets us fold an `fsync` into the preceding write, and `RWF_NOCACHE` in `Eio.Flow.copy` can stop bulk copies from trashing the page cache.  Both of these will in turn help add better [batched copy](https://github.com/ocaml-multicore/eio/pull/748) support directly into Eio for things like shifting Zarr files around.
- [PR \#155](https://github.com/ocaml-multicore/ocaml-uring/pull/155) sorts out vectored `readv`/`writev` fixed-buffer stubs which were misnamed before. I need to knock up a benchmark suite to figure out why fixed buffers are underperforming so much, but it would help to actually do vectored IO into them\!
- A bigger change is [PR \#153](https://github.com/ocaml-multicore/ocaml-uring/pull/153) which switches the underlying buffer type from bigarray/cstruct over to plain `bytes`. It's a surprisingly small diff since [Sadiq Jaffer](https://toao.com) pointed out that bytes in the [OCaml 5 runtime](https://anil.recoil.org/papers/2020-icfp-retropar) never actually relocate unless they're small (\<2KB). [Patrick Ferris](https://patrick.sirref.org) had also done a similar [experiment](https://github.com/ocaml-multicore/ocaml-uring/pull/101). I think this will need to rejig who actually allocates the buffers, since [IO memory needs to be caller allocated](https://anil.recoil.org/papers/2012-resolve-fable) where possible.

On the Eio side, the work is mostly about getting these new capabilities up into a portable form where applications can actually reach them:

- [PR \#850](https://github.com/ocaml-multicore/eio/pull/850) adds `ftruncate`/`fdatasync` and routes `fsync`, `shutdown` and `socket` through uring instead of the blocking fallbacks, so the whole file path stays on the shared ring. It's just generally useful to avoid syscalls, although it would be unusual to have any of these be a bottleneck (vs read/write).
- [PR \#854](https://github.com/ocaml-multicore/eio/pull/854) propagates the real `errno` back out of the "fork actions" C binding into `Eio.Process`, so a failed `exec` raises a precise `Unix.Unix_error`. This in turn makes it much easier to add [pseudoterminal support](https://github.com/ocaml-multicore/eio/pull/531), which I started back in 2023 (!) for [Ryan Gibb](https://ryan.freumh.org) and might actually finish this year.
- Still in flight is another longstanding PR in the form of [`Eio_unix.Sockopt`](https://github.com/ocaml-multicore/eio/pull/575) module for getting and setting socket options, so things like capnp-rpc can control TCP behaviour better.

[Thomas Leonard](https://github.com/https://roscidus.com) has meanwhile been simplifying the scheduler around by [moving the fixed-buffer read/write retries out of the scheduler](https://github.com/ocaml-multicore/eio/pull/849) and [coping gracefully](https://github.com/ocaml-multicore/eio/pull/852) when there isn't enough lockable memory for the ring itself. None of this is glamorous, but it's the bedrock on which a lot of my OCaml code depends, so I'm very happy to put the effort into getting my piece of it right.

## Going hyper local with in-process LLMs

I was midway through an agent-assisted sweep of the OCaml runtime with Claude Fable when it abruptly [cut out on me](https://www.theverge.com/ai-artificial-intelligence/949553/anthropic-fable-5-mythos-5-government-national-security). The suddenness was enough to get me serious about trying some open-weights models I can run myself.

I [bound Antirez](https://github.com/antirez)' [Dwarfstar](https://github.com/antirez/ds4) DeepSeek-v4 engine into OCaml 5 and Eio as an ordinary library, and built a small agent up from primitives on top of it. I wrote it up [in its own post](https://anil.recoil.org/notes/language-integrated-llms), but the TL;DR is that it works surprisingly well for local customisation. The model is just a plain OCaml function call, its tools are ordinary OCaml functions, and there are no serialisation woes with REST endpoints, MCP servers or external services anywhere.

Since that post, I *have* been surprised to see how many weird things I can do with it: for example, I've currently got a process that's using OCaml's runtime events to introspect itself and use the builtin LLM to modify its own GC parameters. The LLM can understand some pretty low-level system concepts...

<figure class="image-center"><img src="/images/humpty-ss-1.webp" alt="The Humpty OCaml deepseek agent in full poetic flow" title="The Humpty OCaml deepseek agent in full poetic flow" loading="lazy" srcset="/images/humpty-ss-1.768.webp 768w, /images/humpty-ss-1.640.webp 640w, /images/humpty-ss-1.480.webp 480w, /images/humpty-ss-1.320.webp 320w, /images/humpty-ss-1.1920.webp 1920w, /images/humpty-ss-1.1600.webp 1600w, /images/humpty-ss-1.1440.webp 1440w, /images/humpty-ss-1.1280.webp 1280w, /images/humpty-ss-1.1024.webp 1024w"><figcaption>The Humpty OCaml deepseek agent in full poetic flow</figcaption></figure>

## Self-hosted email feedback and DKIM2

My [self-hosting email post](https://anil.recoil.org/notes/recoil-self-hosting-2026) from a couple of weeks ago is drawing surprisingly useful feedback. David Verdin [pointed out](https://amok.recoil.org/@dverdin@mastodon.gougere.fr/116719835417239805) that the DKIM signing (which I find really complicated) is going through a revision.

[DKIM2](https://datatracker.ietf.org/doc/draft-ietf-dkim-dkim2-motivation/) is in IETF draft form, with the headline change being that every hop in the email delivery chain now signs the message rather than just the originating server. That fixes two things that make DKIM(1) brittle: the signature breakage you get when a forwarder or mailing list touches a message, and replay attacks where a legitimately-signed message is re-spammed to millions.

The [latest spec draft](https://datatracker.ietf.org/doc/draft-ietf-dkim-dkim2-spec/) arrived last month and ensures that existing keys stay compatible. It's still (like JMAP) not widely deployed yet, with big mailbox providers promising the end of the year.  I'm pretty glad to see email continues to maintain a story for independent hosting\!

I also got pinged by the founder of [CoMail](https://comail.at/), which is a cooperative ATProto based email service that uses the social database to verify identity instead. This seems related to some of the thoughts on [Tangled vouching](https://oppi.li/weeklies/2026-19/) from a few weeks ago, as that also uses the ATProto.

## Fun and not fun links

I wrapped up my [Royal Society](https://royalsociety.org) International Newton
panel reviews and my share of Cambridge exam marking. But then I had to roll
straight into reviewing for [EuroSys](https://www.eurosys.org) and their
resubmission round (since I reviewed earlier versions of the paper in a
previous iteration of the conference)  and also get new papers dropping in from
editors in remote-sensing journals.  I don't begrudge any of it individually,
of course, but something has to change about peer review to make it more
sustainable in the coming years. Or maybe [we'll just learn not to sleep](https://www.nature.com/articles/s41593-026-02318-9).

On more fun topics:
- Josh Bressers argues that [we have to change the rules of security](https://opensourcesecurity.io/2026/06-rules-of-security/) (even with Mythos offline) since security teams are drowning in CVEs and alerts. The only lever left is choosing what *not* to respond to as time-gating and not updating too fast [came up last week](https://anil.recoil.org/notes/2026w23) from the ExploitGym benchmark as well. Maybe my local LLM agents will mutate their way into protecting themselves...
- A lovely [history of how photosynthesis evolved](https://www.quantamagazine.org/an-early-step-on-the-long-strange-road-to-photosynthesis-20260610/) in Quanta last week, told through a newly-discovered Panamanian bacterium whose paddle-shaped light-harvesting machinery hasn't changed in billions of years. The article is also beautifully laid out.
- I continue to greatly enjoy [Amol Rajan's podcasts and the latest one](https://www.bbc.co.uk/sounds/play/m002xh09) on "The End of Endless Growth: Should We Put the Brakes on Economic Expansion?". This _doesn't_ promote degrowth (which will never happen and is probably more harmful than good to individuals) but rather has an excellent discussion with [Kate Raworth](https://en.wikipedia.org/wiki/Kate_Raworth) on [Doughnut economics](https://en.wikipedia.org/wiki/Doughnut_\(economic_model\)) and planetary boundaries.
- Welcome [Lachlan Kermode to the addiction of weeknotes](https://weeknotes.ohrg.org/w24-2026).
Synopsis: Made professor at Cambridge, shipped TESSERA v1.1, bound a local DeepSeek into OCaml after Fable cut out, and filled the gaps in io_uring and Eio.
Words: 1767

## Related

- [Language integrated LLMs as an OCaml function](https://anil.recoil.org/notes/language-integrated-llms) (note, 2026-06-14)
- [Tessera v1 and v1.1 coverage map](https://anil.recoil.org/videos/97d422a2-af9c-47b5-947a-c136ad7093b6) (video, 2026-06-12)
- [Tessera v1.1 released, with smoother and temporally stable embeddings](https://anil.recoil.org/notes/tessera-v11-out) (note, 2026-06-12)
- [.plan-26-23: Earth Embeddings, Emails Everywhere, and ERRNOOOs](https://anil.recoil.org/notes/2026w23) (note, 2026-06-07)
- [Self-hosting email the hard way from your own routable IPv4 block up](https://anil.recoil.org/notes/recoil-self-hosting-2026) (note, 2026-06-06)
- [TESSERA: Temporal Embeddings of Surface Spectra for Earth Representation and Analysis](https://anil.recoil.org/papers/2025-tessera) (paper, 2025-11-01)
- [Retrofitting parallelism onto OCaml](https://anil.recoil.org/papers/2020-icfp-retropar) (paper, 2020-08-01)
- [The case for reconfigurable I/O channels](https://anil.recoil.org/papers/2012-resolve-fable) (paper, 2012-03-01)

---
Canonical: https://anil.recoil.org/notes/2026w24
Type: note
Tags: ocaml, eio, linux, ai, llm, tessera, selfhosting, email, security, academia
