2025 Advent of Agentic Humps: Building a useful O(x)Caml library every day / Dec 2025
Agentic programming has been getting a hilariously bad rap in the OCaml community recently, but it's definitely here to stay despite the
Day 1: Crockford for Crockford Base32 encoding.Day 2: Jsonfeed for an implementation of the JSONFeed 1.1 spec.Day 3: XDGe for a XDG Directory specifiction with Eio capabilities.Day 4: Claudeio for a Claude OCaml/Eio SDK so I can use Claude to write more Eio.Day 5: Bytesrw-eio Bytesrw/Eio adapter and automate opam metadata via a custom Claude skill.Day 6: Yamlrw for a pure OCaml Yaml 1.2 library, to replace ocaml-yaml's C binding.Day 7: Yamlt to allow jsont codecs to be serialised to Yaml as well as JSON.Day 8: Sortal : a contacts management CLI using Yaml, Git and Cmdliner.Day 9: Sortal-Bonsai : adding aBonsai_termterminal UI to Sortal via Async.Day 10: Sortal-Mosaic : adding aMosaicterminal UI to Sortal via Eio.Day 11: Cookeio, Public-suffix, Punycode : parsing Internet RFCs to build cookie libraries.Day 12: Conpool : Eio TLS/TCP connection pooling and self-contained performance viz.Day 13: Requests : Heckling an OCaml HTTP client from 50 other implementations.Day 14: Karakeep : Live agentic API construction for the Karakeep app.Day 15: Htmlrw : Vibespiling Rust/Python into a 100% compliant HTML5 manipulation library.Day 16: Json-pointer : Vibesplaining specifications by generating OCaml Javascript notebooks.Day 17: Jmap : Vibemailing little CLI agents to bring my JMAP messages under control.Day 18: Tomlt : Elegant TOML 1.1 codecs inspired by the jsont data soup paper.Day 19: Zulip, INIt : Zulip bot framework and INI codecs compatible with Python configparser.Day 20: Langdetect : Statistical detection for human languages in OCaml, JavaScript and wasm.Day 21: Html5rw_check : Vibespiling the Nu HTML Validator from Java to typed OCaml checkers.Day 22: Monopam : Monorepo workflow with dune vendoring for cross-cutting fixes.Day 23: Unpac : Unifying git and opam package management with branch-based monorepos.Day 24: Tuatara : Tuatara, an evolving Atom aggregator that mutates its own code.Day 25: OCaml Claude Marketplace : Wrapping up my Claude skills into a reusable bundle.
Read full note... (1594 words)
AoAH Day 25: Claude OCaml Marketplace for all your festive coding needs / Dec 2025
I'm somewhat frazzled after managing to get through
In the past, my computer systems brain was limited by the speed of coding, but now it feels like we're entering a different age. I'll reserve my longform thoughts on all of this for the new year as I need to head into Christmas festivities, but I wanted to leave you all with my Claude Code OCaml marketplace in case you want to try this stuff for yourself!
AoAH Day 24: Tuatara, an evolving Atom aggregator that mutates / Dec 2025
My original purpose for starting this
I'm not sure if taking the longest way around was wise here but I ended up building tuatara, an aggregator to pull together all my colleagues' writing into one place. They're a quirky bunch with many diverse homegrown feeds in various states of brokenness, so it's difficult to build a one-size-fits-all tool.
So given it's the end of the year and I'm sozzled on Christmas eve on
mulled wine, I decided to make Tuatara mutate its own code by linking with my
Read full note... (1126 words)
AoAH Day 23: Unpac unifies git branching with package management / Dec 2025
Yesterday's
Coding agents work best when all relevant code is locally available so
they can grep and make
To fix this, unpac parses package metadata and materialises it into a git branch structure in a single repository to make vendoring, patching, and updating a native git workflow. Local changes can later be exported into git patches for sending upstream, but in the meanwhile our agents can work on a single repository.
The secret sauce to working on so many branches is to use git worktrees, which allow multiple
branches to be checked out simultaneously from one git repo! I'll explain how unpac works next, and you can
browse a working unpac tree. You do end up with a
lot of git branches, which got me banned from GitHub back when I announced Docker DataKit. Luckily this time around I am hosting on

Read full note... (2271 words)
Dear ACM, you're doing AI wrong but you can still get it right / Dec 2025 / DOI
There's outrage in the computer science community over a new feature rolled out by the ACM Digital Library that generates often inaccurate AI summaries. To make things worse, this is hidden behind a 'premier' paywall, so authors without access (for example, having graduated from University) can't even see what is being said.
Read full note... (2046 words)
AoAH Day 22: Assembling monorepos for agentic OCaml development / Dec 2025
Over the past three weeks, I've accumulated dozens of OCaml repositories as
part of this
Today I'm switching tacks to address this with a monorepo workflow built around dune's
excellent vendoring support.
I last visited this when building
I also wanted to explore the small group dynamic around vibecoding tools. For today's tool, I first asked
Read full note... (1855 words)
AoAH Day 21: Complete dynamic HTML5 validation in OCaml and the browser / Dec 2025
With
The result is a pure OCaml HTML5 conformance checker that integrates with the
Read full note... (1656 words)
AoAH Day 20: Human language detection in native code, JS and wasm / Dec 2025
I took a break from yesterday's bot hacking to continue the
I decided to split this work into two days, and started with a simple problem: HTML5 validation includes the need for automated language detection to validate that the lang attribute on HTML elements matches the actual content. This is important for accessibility, as screen readers use language hints to select the correct pronunciation.
The W3C validator uses the Cybozu langdetect algorithm, so I vibespiled this into pure OCaml code as ocaml-langdetect. However, I decided to push harder by compiling this to three different backends: native code OCaml, JavaScript via js_of_ocaml and then into modern WebAssembly using wasm_of_ocaml. As a fun twist, I got the regression tests running as interactive "
Read full note... (1445 words)
AoAH Day 19: Zulip bot framework to bring Vicuna the friendly camel back / Dec 2025
After building .zuliprc files rather than TOML, woops! But this gave me the perfect opportunity to attempt to quickly replicate the tomlt experience with a third config format codec library for Windows-style INI files as well.
So today I released both ocaml-zulip for Zulip API integration and ocaml-init for INI file codecs that are compatible with Pythonic features such as variable interpolation. Along the way, I developed a new regression test mechanism by writing a Zulip bot that tests the Zulip API using OCaml Zulip!
Read full note... (1591 words)
AoAH Day 18: TOML 1.1 codecs directly from the spec and paper / Dec 2025
After getting my
What I wanted to explore with this library is whether I could use a coding agent to build a complex functional abstraction from scratch. After building
Read full note... (1136 words)
AoAH Day 17: OCaml JMAP to plaster my painful email papercuts / Dec 2025
After building a
Luckily, I've been self-hosting my
Read full note... (1707 words)
AoAH Day 16: Vibesplaining JSON Pointers using OCaml/Javascript / Dec 2025
After the successful
I decided to build a JMAP email client implementation in
OCaml that I need for myself Being a professor is not accurately measured by research or teaching outputs, but by how overloaded your INBOX is.
OCaml has superb tooling to help with this; it can not only compile to efficient native code but also to JavaScript and WASM that runs standalone in the browser. I turned to my colleagues
Today's work resulted in an ocaml-json-pointer (RFC6901) implementation along with an interactive notebook tutorial that bundles the entire OCaml compiler toolchain alongside it. There's even another one for Yaml just to illustrate how easy this is to replicate once we've built the first one.
Read full note... (1573 words)
AoAH Day 15: Porting a complete HTML5 parser and browser test suite / Dec 2025
After my success with
My question, though, is how difficult is to go in the other direction and move towards a strongly typed interface like OCaml's. Could we ultimately distill down the extremely complex set of rules around parsing HTML all the way into a proof assistant like Lean, but hopping via OCaml and Haskell to provide convenient executable pitstops?
Today's task was to vibespile the Python into ocaml-html5rw, a pure OCaml HTML5 parser and serialiser that passes the browser test suite 100%.
Read full note... (1387 words)
AoAH Day 14: Debugging a Karakeep CLI against the live service / Dec 2025
With the
To start with, I use Karakeep across all my devices to bookmark things, and I'd like to be able to programmatically search through tags, for example by taking all outbound links from the blogs that I read and autosynching them with my remote service. Karakeep on the server side does some cool things like screenshot links and create local webarchives.
Unfortunately, Karakeep doesn't publish an OCaml interface. Fortunately, my new bestie Claude helped me build ocaml-karakeep without much input from me!
AoAH Day 13: Heckling an OCaml HTTP client from 50 implementations in 10 languages / Dec 2025
Now I had some
Luckily, there's an
I'm not sure what the collective verb is for a group of HTTP clients, so dubbed this whole process a 'heckle' of HTTP coding!
Read full note... (2006 words)
AoAH Day 12: Eio Connection pooling and event tracing / Dec 2025
After yesterday's
For example, github.io has four A records:
> host github.io
github.io has address 185.199.110.153
github.io has address 185.199.109.153
github.io has address 185.199.108.153
github.io has address 185.199.111.153
With this new connection pooling library, my application should be able to
connect to the github.io name and keep track of all the outgoing connections
on the basis of it being called github.io and load balance the number of
outgoing connections accordingly.
In the interests of exploring something new, I also decided to add in visualisation
support to figure out what the library is spending its time on.
I decided to generate self-contained visualisations,
inspired by
AoAH Day 11: HTTP Cookies and vibing RFCs for breakfast / Dec 2025
I'm switching focus for a few days to build a complete HTTP(S) client to use in my
So I thought I'd have a go at a different approach today using agentic coding: can we synthesise a complete HTTP Cookie implementation purely from the RFC 6265 prose itself, and then differentially compare this OCaml implementation against the others? In theory, running a single test suite across all three libraries might be a good way of discovering how to improve the existing implementations. In the long-term, http-cookie is probably the upstream library I want to use, but I don't want to generate a giant diff against it today due to my
Read full note... (1631 words)
AoAH Day 10: Building a TUI for Sortal using Mosaic / Dec 2025
After building a reasonably complete
I first noticed this library when Thibaut presented his OCaml coding with AI talk at FunOCaml. It's quite different from Bonsai in that Mosaic uses OCaml's effects to provide a more direct-style API, and so seems worth experimenting with. So today's task is to port Sortal to use Mosaic and see what this terminal UI looks like!
AoAH Day 9: Adding a Bonsai terminal UI to Sortal / Dec 2025
After building a reasonably complete
Read full note... (1040 words)
Publish, Review, Curate to upend scholarly publishing / Dec 2025 / DOI
I was not expecting to find a bunch of activist librarians at the lovely spires of King's College Chapel last week, but I was very glad that I did! I gave a talk to the Confederation of Open Access Repositories group that was having a meeting about "Turning scholarly publishing on its head". Luckily, I had my budding
Read full note... (1562 words)
AoAH Day 8: Building a contacts CLI manager with Sortal / Dec 2025
I've been accumulating a lot of contacts that I use to write cross references
on my website. This works by using
Cmarkit to parse my custom Markdown,
and spot entries like [@sadiqj] and convert those into a full reference like
Today, I want to build a full CLI application that stores all my contacts as Yaml files in my home directory using XDG conventions, and give me a simple search interface so I can quickly autocomplete these posts from my editor. I call this little application "Sortal".
AoAH Day 7: Converting between JSON and Yaml with yamlt / Dec 2025
After the excitement of building an entire
AoAH Day 6: Getting a Yaml 1.2 implementation in pure OCaml / Dec 2025
I did the palate cleanser of
Since Yaml is an monstrously convoluted spec, I opted back then to bind to the C libyaml using
And the worst thing is, I cannot find the motivation to figure out how Yaml really works. It's the world's worst serialisation format, with lots of corner cases and memory blowups inherent in how it works. So I decided to dive in and see if I could build a pure OCaml Yaml 1.2 implementation using bytesrw and the source spec.
TL;DR: it worked. It actually seems to have come up with a reasonable, pure OCaml implementation that I'm now using! It needs more validation and external code review, but this has been on my TODO list for years now.
AoAH Day 5: Bytesrw Eio adapters and automating opam metadata / Dec 2025
After the
AoAH Day 4: Going recursive with Claudeio for Claude / Dec 2025
By this point, I've got three useful libraries and my use of Claude is getting better. So naturally I want to automate my invocations of the claude CLI, but I hit a roadblock: there are no OCaml SDK bindings! However, there appear to be SDKs in Python, Go and many others. So today will involve having a stab at generating Claude OCaml bindings using Eio, so I can use Claude to write more OCaml!